Меню

Главная
Случайная статья
Настройки
Адаптер (шаблон проектирования)
Материал из https://ru.wikipedia.org

Адаптер (англ. Adapter) — структурный шаблон проектирования, предназначенный для организации использования функций объекта, недоступного для модификации, через специально созданный интерфейс. Другими словами — это структурный паттерн проектирования, который позволяет объектам с несовместимыми интерфейсами работать вместе.

Содержание

Основные характеристики

Задача

Система поддерживает требуемые данные и поведение, но имеет неподходящий интерфейс.

Способ решения

Адаптер предусматривает создание класса-оболочки[1] с требуемым интерфейсом.

Участники

Класс Adapter приводит интерфейс класса Adaptee в соответствие с интерфейсом класса Target (который реализуется классом Adapter). Это позволяет объекту Client использовать объект Adaptee (посредством адаптера Adapter) так, словно он является экземпляром класса Target.

Таким образом Client обращается к интерфейсу Target, реализованному классом Adapter, который перенаправляет обращение к Adaptee.



Следствия

Шаблон Адаптер позволяет включать уже существующие объекты в новые объектные структуры, независимо от различий в их интерфейсах.

Замечания и комментарии

Шаблон Адаптер позволяет в процессе проектирования не принимать во внимание возможные различия в интерфейсах уже существующих классов. Если есть класс, обладающий требуемыми методами и свойствами (по крайней мере, концептуально), то при необходимости всегда можно воспользоваться шаблоном Адаптер для приведения его интерфейса к нужному виду.

Близким Адаптеру является шаблон Фасад, не всегда можно отличить один от другого[2].

Применение шаблона

Типичным примером использования шаблона Адаптер можно назвать создание классов, приводящих к единому интерфейсу функции языка PHP обеспечивающие доступ к различным СУБД[3].

Вариант решения данной проблемы с использованием шаблона Адаптер показан на рисунке.

Реализация

Включение уже существующего класса в другой класс. Интерфейс включающего класса приводится в соответствие с новыми требованиями, а вызовы его методов преобразуются в вызовы методов включённого класса.




Шаги реализации
  1. Убедитесь, что у вас есть два класса с несовместимыми интерфейсами:
    • полезный сервис — служебный класс, который вы не можете изменять (он либо сторонний, либо от него зависит другой код);
    • один или несколько клиентов — существующих классов приложения, несовместимых с сервисом из-за неудобного или несовпадающего интерфейса.
  2. Опишите клиентский интерфейс, через который классы приложения смогли бы использовать класс сервиса.
  3. Создайте класс адаптера, реализовав этот интерфейс.
  4. Поместите в адаптер поле, которое будет хранить ссылку на объект сервиса. Обычно это поле заполняют объектом, переданным в конструктор адаптера. В случае простой адаптации этот объект можно передавать через параметры методов адаптера.
  5. Реализуйте все методы клиентского интерфейса в адаптере. Адаптер должен делегировать основную работу сервису.
  6. Приложение должно использовать адаптер только через клиентский интерфейс. Это позволит легко изменять и добавлять адаптеры в будущем.





Ruby
module AdapterPattern
  # Allows Client to use Adaptees with incompatible interfaces via Adapters with interface Target

  # Adaptee
  class Twitter
    def twit
      puts 'Twit was published'
    end
  end

  # Adaptee
  class Facebook
    def post
      puts 'Facebook post was published'
    end
  end

  # Target
  module WebServiceInterface
    def send_message
      raise NotImplementedError
    end
  end

  # Adapter
  class TwitterAdapter
    include WebServiceInterface

    def initialize
      @webservice = Twitter.new
    end

    def send_message
      @webservice.twit
    end
  end

  # Adapter
  class FacebookAdapter
    include WebServiceInterface

    def initialize
      @webservice = Facebook.new
    end

    def send_message
      @webservice.post
    end
  end

  # Client
  class Message
    attr_accessor :webservice

    def send
      @webservice.send_message
    end
  end

  def self.run
    puts '=>  Adapter'

    message = Message.new

    message.webservice = TwitterAdapter.new
    message.send

    message.webservice = FacebookAdapter.new
    message.send

    puts ''
  end
end

AdapterPattern.run


Java - наследование
Downgrade Counter