- Адаптер (шаблон проектирования)
-
Шаблон проектирования Адаптер Adapter Тип: структурный
Назначение: для организации использования функций объекта, недоступного для модификации, через специально созданный интерфейс (приводит интерфейс класса (или нескольких классов) к интерфейсу требуемого вида)
Применяется в случаях: система поддерживает требуемые данные и поведение, но имеет неподходящий интерфейс. Чаще всего шаблон Адаптер применяется если необходимо создать класс, производный от вновь определяемого или уже существующего абстрактного класса.
Плюсы: - инкапсуляция реализации внешних классов (компонентов, библиотек), система становится независимой от интерфейса внешних классов;
- переход на использование других внешних классов не требует переделки самой системы, достаточно реализовать один класс
Adapter
.
Родственные шаблоны: Описан в Design Patterns Да
Адаптер, Adapter или Wrapper/Обёртка — структурный шаблон проектирования, предназначенный для организации использования функций объекта, недоступного для модификации, через специально созданный интерфейс.
Содержание
Основные характеристики
Задача
Система поддерживает требуемые данные и поведение, но имеет неподходящий интерфейс. Чаще всего шаблон Адаптер применяется, если необходимо создать класс, производный от вновь определяемого или уже существующего абстрактного класса.
Способ решения
Адаптер предусматривает создание класса-оболочки[1] с требуемым интерфейсом.
Участники
Класс
Adapter
приводит интерфейс классаAdaptee
в соответствие с интерфейсом классаTarget
(наследником которого являетсяAdapter
). Это позволяет объектуClient
использовать объектAdaptee
(посредством адаптераAdapter
) так, словно он является экземпляром классаTarget
.Таким образом
Client
обращается к интерфейсуTarget
, реализованному в наследникеAdapter
, который перенаправляет обращение кAdaptee
.Следствия
Шаблон Адаптер позволяет включать уже существующие объекты в новые объектные структуры, независимо от различий в их интерфейсах.
Реализация
Включение уже существующего класса в другой класс. Интерфейс включающего класса приводится в соответствие с новыми требованиями, а вызовы его методов преобразуются в вызовы методов включённого класса.
Пример на Java (class adapter)
Исходный текст на языке Java (class adapter)// Target public interface Chief { public Object makeBreakfast(); public Object makeLunch(); public Object makeDinner(); } // Adaptee public class Plumber { public Object getScrewNut() { ... } public Object getPipe() { ... } public Object getGasket() { ... } } // Adapter public class ChiefAdapter extends Plumber implements Chief { public Object makeBreakfast() { return getGasket(); } public Object makeLunch() { return getPipe(); } public Object makeDinner() { return getScrewNut(); } } // Client public class Client { public static void eat(Object dish) { ... } public static void main(String[] args) { Chief ch = new ChiefAdapter(); Object dish = ch.makeBreakfast(); eat(dish); dish = ch.makeLunch(); eat(dish); dish = ch.makeDinner(); eat(dish); callAmbulance(); } }
Пример на Java (object adapter)
Исходный текст на языке Java (object adapter)package com.designpatterns.objectadapter; /* Файл Chief.java * * */ public interface Chief { public Object makeBreakfast(); public Object makeDinner(); public Object makeSupper(); } package com.designpatterns.objectadapter; /* Файл Plumber.java * * */ public class Plumber { public Object getPipe(){ return new Object(); } public Object getKey(){ return new Object(); } public Object getScrewDriver(){ return new Object(); } } package com.designpatterns.objectadapter; /* Файл ChiefAdapter.java * * */ public class ChiefAdapter implements Chief{ private Plumber plumber = new Plumber(); @Override public Object makeBreakfast() { return plumber.getKey(); } @Override public Object makeDinner() { return plumber.getScrewDriver(); } @Override public Object makeSupper() { return plumber.getPipe(); } } package com.designpatterns.objectadapter; /* Файл Client.java * * */ public class Client { public static void main (String [] args){ Chief chief = new ChiefAdapter(); Object key = chief.makeDinner(); } }
Пример реализации на PHP5
Исходный текст на языке PHP5class Search { private $text; private $word; function __construct($text,$word) { $this->text = $text; $this->word = $word; } function searchWordInText() { return $this->text; } function getWord() { return $this->word; } } class SearchAdapter { private $aSearch; function __construct(Search $aSearch) { $this->aSearch = $aSearch; } function searchWordInText() { return 'Эти слова '.$this->aSearch->getWord().' найдены в тексте '.$this->aSearch->searchWordInText(); } } $search = new Search("текст", "слова"); $searchAdapter = new SearchAdapter($search); echo $searchAdapter->searchWordInText();
Пример на Python
Исходный текст на языке Pythonclass GameConsole: def create_game_picture(self): return 'picture from console' class Antenna: def create_wave_picture(self): return 'picture from wave' class SourceGameConsole(GameConsole): def get_picture(self): return self.create_game_picture() class SourceAntenna(Antenna): def get_picture(self): return self.create_wave_picture() class TV: def __init__(self, source): self.source = source def show_picture(self): return self.source.get_picture() g = SourceGameConsole() a = SourceAntenna() game_tv = TV(g) cabel_tv = TV(a) print game_tv.show_picture() print cabel_tv.show_picture()
Замечания и комментарии
Шаблон Адаптер позволяет в процессе проектирования не принимать во внимание возможные различия в интерфейсах уже существующих классов. Если есть класс, обладающий требуемыми методами и свойствами (по крайней мере, концептуально), то при необходимости всегда можно воспользоваться шаблоном Адаптер для приведения его интерфейса к нужному виду.
Близким Адаптеру является шаблон Фасад, не всегда можно отличить один от другого[2].
Применение шаблона
Типичным примером использования шаблона Адаптер можно назвать создание классов, приводящих к единому интерфейсу функции языка PHP обеспечивающие доступ к различным СУБД[3].
Вариант решения данной проблемы с использованием шаблона Адаптер показан на рисунке.
C#
Исходный текст на языке C#using System; namespace Adapter { class MainApp { static void Main() { // Create adapter and place a request Target target = new Adapter(); target.Request(); // Wait for user Console.Read(); } } // "Target" class Target { public virtual void Request() { Console.WriteLine("Called Target Request()"); } } // "Adapter" class Adapter : Target { private Adaptee adaptee = new Adaptee(); public override void Request() { // Possibly do some other work // and then call SpecificRequest adaptee.SpecificRequest(); } } // "Adaptee" class Adaptee { public void SpecificRequest() { Console.WriteLine("Called SpecificRequest()"); } } }
Примечания
- ↑ Близость значений терминов оболочка и обёртка (англ. wrapper — используется как синоним декоратора) иногда приводит к путанице и Адаптер определяют как синоним шаблона Декоратор, в то время как это два разных шаблона и последний решает иную задачу, а именно: подключение дополнительных обязательств к объекту.
- ↑ Разница состоит в том, что шаблон Фасад предназначен для упрощения интерфейса, тогда как шаблон Адаптер предназначен для приведения различных существующих интерфейсов к единому требуемому виду.
- ↑ В языке PHP доступ к СУБД реализован в виде набора функций, для каждой СУБД они имеют различные наименования и, иногда, различный набор используемых параметров, что приводит к значительным проблемам при переходе с одной СУБД на другую, если такой переход заранее не обеспечен использованием шаблона Адаптер.
Литература
- Алан Шаллоуей, Джеймс Р. Тротт. Шаблоны проектирования. Новый подход к объектно-ориентированному анализу и проектированию = Design Patterns Explained: A New Perspective on Object-Oriented Design. — М.: «Вильямс», 2002. — С. 288. — ISBN 0-201-71594-5
- Э. Гамма, Р. Хелм, Р. Джонсон, Дж. Влиссидес Приемы объектно-ориентированного проектирования. Паттерны проектирования = Design Patterns: Elements of Reusable Object-Oriented Software. — СПб: «Питер», 2007. — С. 366. — ISBN 978-5-469-01136-1 (также ISBN 5-272-00355-1)
Ссылки
- Паттерн проектирования «Адаптер» на Хабрахабре
- Паттерн Adapter (Адаптер) — назначение, описание, реализация на С++, достоинства и недостатки
Шаблоны проектирования Основные Порождающие Структурные Адаптер • Выделение частного класса данных • Декоратор • Заместитель • Компоновщик • Мост • Приспособленец • Фасад
Поведенческие Интерпретатор • Итератор • Команда • Наблюдатель • Посетитель • Посредник • Состояние • Стратегия • Хранитель • Цепочка обязанностей • Шаблонный метод
Блокировка с двойной проверкой • Однопоточное выполнение • Планировщик Категории:- Шаблоны проектирования
- Структурные шаблоны проектирования
Wikimedia Foundation. 2010.