Адаптер | |
Adapter | |
Тип: |
структурный |
---|---|
Назначение: |
для организации использования функций объекта, недоступного для модификации, через специально созданный интерфейс (приводит интерфейс класса (или нескольких классов) к интерфейсу требуемого вида) |
Применяется в случаях: |
система поддерживает требуемые данные и поведение, но имеет неподходящий интерфейс. Чаще всего шаблон Адаптер применяется если необходимо создать класс, производный от вновь определяемого или уже существующего абстрактного класса. |
Плюсы: |
|
Родственные шаблоны: | |
Описан в Design Patterns |
Да |
Адаптер, Adapter или Wrapper/Обёртка — структурный шаблон проектирования, предназначенный для организации использования функций объекта, недоступного для модификации, через специально созданный интерфейс.
Содержание |
Система поддерживает требуемые данные и поведение, но имеет неподходящий интерфейс. Чаще всего шаблон Адаптер применяется, если необходимо создать класс, производный от вновь определяемого или уже существующего абстрактного класса.
Адаптер предусматривает создание класса-оболочки[1] с требуемым интерфейсом.
Класс Adapter
приводит интерфейс класса Adaptee
в соответствие с интерфейсом класса Target
(наследником которого является Adapter
). Это позволяет объекту Client
использовать объект Adaptee
(посредством адаптера Adapter
) так, словно он является экземпляром класса Target
.
Таким образом Client
обращается к интерфейсу Target
, реализованному в наследнике Adapter
, который перенаправляет обращение к Adaptee
.
Шаблон Адаптер позволяет включать уже существующие объекты в новые объектные структуры, независимо от различий в их интерфейсах.
Включение уже существующего класса в другой класс. Интерфейс включающего класса приводится в соответствие с новыми требованиями, а вызовы его методов преобразуются в вызовы методов включённого класса.
// 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(); } }
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(); } }
class 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].
Вариант решения данной проблемы с использованием шаблона Адаптер показан на рисунке.
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()"); } } }
Адаптер (шаблон проектирования).