Адаптер
Adapter
Представление структуры шаблона Адаптер
Представление структуры шаблона Адаптер
Тип структурный
Назначение для организации использования функций объекта, недоступного для модификации, через специально созданный интерфейс (приводит интерфейс класса (или нескольких классов) к интерфейсу требуемого вида)
Применяется в случаях система поддерживает требуемые данные и поведение, но имеет неподходящий интерфейс. Чаще всего шаблон Адаптер применяется если необходимо создать класс, производный от вновь определяемого или уже существующего абстрактного класса.
Плюсы
  • инкапсуляция реализации внешних классов (компонентов, библиотек), система становится независимой от интерфейса внешних классов;
  • переход на использование других внешних классов не требует переделки самой системы, достаточно реализовать один класс Adapter.
Родственные шаблоны Фасад, Декоратор
Описан в Design Patterns Да

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

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

править

Задача

править

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

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

править

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

Участники

править

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

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

Следствия

править

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

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

править

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

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

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

править

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

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

Пример использования шаблона Адаптер

Реализация

править

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


Шаги реализации

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


Ruby

править

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

править

Java - композиция

править

Scala

править

PHP5

править

PHP5.4

править

PHP5.4 Compact

править

JavaScript

править

Python

править

C# - композиция

править

С# - наследование

Delphi

править

Примечания

править
  1. Близость значений терминов оболочка и обёртка (англ. wrapper — используется как синоним декоратора) иногда приводит к путанице и Адаптер определяют как синоним шаблона Декоратор, в то время как это два разных шаблона и последний решает иную задачу, а именно: подключение дополнительных обязательств к объекту.
  2. Разница состоит в том, что шаблон Фасад предназначен для упрощения интерфейса, тогда как шаблон Адаптер предназначен для приведения различных существующих интерфейсов к единому требуемому виду.
  3. В устаревших версиях языка 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)
  • Эрик Фримен, Элизабет Фримен. Паттерны проектирования = Head First Design Patterns. — СПб.: Питер, 2011. — 656 с. — ISBN 978-5-459-00435-9.

Ссылки

править

📚 Artikel Terkait di Wikipedia

C++26

лямбда-функциях: template <typename T, auto ConceptWrapperLambda> concept decays_to = requires { ConceptWrapperLambda.template operator()<std::decay_t<T>>();

C++23

автоматов). Уточнено, что common_reference_t — всегда ссылка, а не reference_wrapper. У библиотеки изначально были два варианта: автономная (freestanding) и

Functional (C++)

библиотеки Boost в STL переносились такие классы, как function, bind, mem_fn, result_of, reference_wrapper, hash. Большинство этих изменений, за исключением

Абстрактная фабрика (шаблон проектирования)

factories interface Executor interface Legislator interface Judge // just wrapper for government data class Governor( val name: String, val executor: Executor

C++20

Wrapper(U const& u) : t_(u) {} T t_; }; // Стало template<class T> struct Wrapper { template<class U> explicit(!std::is_convertible_v<U, T>) Wrapper(U

C++11

Doug Gregor (October 22, 2002) A Proposal to add a Polymorphic Function Object Wrapper to the Standard Library ↑  Doc No. 1403: Doug Gregor (November

IUP

сентября 2019 на Wayback Machine — IUP toolkit library for GOBO Eiffel IUP-wrapper является Архивная копия от 26 января 2017 на Wayback Machine частью стандартной

C++ Technical Report 1

namespace std::tr1 reference_wrapper Умные указатели: shared_ptr weak_ptr Определены в заголовочном файле tr1/functional function bind result_of mem_fn Несколько