Меню
Главная
Случайная статья
Настройки
|
Адаптер (англ. Adapter) — структурный шаблон проектирования, предназначенный для организации использования функций объекта, недоступного для модификации, через специально созданный интерфейс. Другими словами — это структурный паттерн проектирования, который позволяет объектам с несовместимыми интерфейсами работать вместе.
Содержание
Основные характеристики
Задача
Система поддерживает требуемые данные и поведение, но имеет неподходящий интерфейс.
Способ решения
Адаптер предусматривает создание класса-оболочки[1] с требуемым интерфейсом.
Участники
Класс Adapter приводит интерфейс класса Adaptee в соответствие с интерфейсом класса Target (который реализуется классом Adapter ). Это позволяет объекту Client использовать объект Adaptee (посредством адаптера Adapter ) так, словно он является экземпляром класса Target .
Таким образом Client обращается к интерфейсу Target , реализованному классом Adapter , который перенаправляет обращение к Adaptee .
Следствия
Шаблон Адаптер позволяет включать уже существующие объекты в новые объектные структуры, независимо от различий в их интерфейсах.
Замечания и комментарии
Шаблон Адаптер позволяет в процессе проектирования не принимать во внимание возможные различия в интерфейсах уже существующих классов. Если есть класс, обладающий требуемыми методами и свойствами (по крайней мере, концептуально), то при необходимости всегда можно воспользоваться шаблоном Адаптер для приведения его интерфейса к нужному виду.
Близким Адаптеру является шаблон Фасад, не всегда можно отличить один от другого[2].
Применение шаблона
Типичным примером использования шаблона Адаптер можно назвать создание классов, приводящих к единому интерфейсу функции языка PHP обеспечивающие доступ к различным СУБД[3].
Вариант решения данной проблемы с использованием шаблона Адаптер показан на рисунке.
Реализация
Включение уже существующего класса в другой класс. Интерфейс включающего класса приводится в соответствие с новыми требованиями, а вызовы его методов преобразуются в вызовы методов включённого класса.
Шаги реализации- Убедитесь, что у вас есть два класса с несовместимыми интерфейсами:
- полезный сервис — служебный класс, который вы не можете изменять (он либо сторонний, либо от него зависит другой код);
- один или несколько клиентов — существующих классов приложения, несовместимых с сервисом из-за неудобного или несовпадающего интерфейса.
- Опишите клиентский интерфейс, через который классы приложения смогли бы использовать класс сервиса.
- Создайте класс адаптера, реализовав этот интерфейс.
- Поместите в адаптер поле, которое будет хранить ссылку на объект сервиса. Обычно это поле заполняют объектом, переданным в конструктор адаптера. В случае простой адаптации этот объект можно передавать через параметры методов адаптера.
- Реализуйте все методы клиентского интерфейса в адаптере. Адаптер должен делегировать основную работу сервису.
- Приложение должно использовать адаптер только через клиентский интерфейс. Это позволит легко изменять и добавлять адаптеры в будущем.
Rubymodule 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 - наследование
|
|