Skip to content

Latest commit

 

History

History
81 lines (51 loc) · 7.73 KB

Adapter.md

File metadata and controls

81 lines (51 loc) · 7.73 KB

Адаптер

UML

Преобразует интерфейс класса к другому интерфейсу, на который рассчитан клиент. Обеспечивает совместную работу классов, невозможную в обычных условиях из-за несовместимости интерфейсов.

Применимость

  • Когда вы хотите использовать сторонний класс, но его интерфейс не соответствует остальному коду приложения.

    • Адаптер позволяет создать объект-прокладку, который будет превращать вызовы приложения в формат, понятный стороннему классу.
  • Когда вам нужно использовать несколько существующих подклассов, но в них не хватает какой-то общей функциональности. Причём расширять суперкласс вы не можете (Похоже на Декоратор).

    • Вы могли бы создать ещё один уровень подклассов, и добавить в них недостающую функциональность. Но при этом придётся дублировать один и тот же код в обеих ветках подклассов.

      Более элегантное решение - поместить недостающую функциональность в адаптер и приспособить его для работы с суперклассом. Такой адаптер сможет работать со всеми подклассами иерархии. Это решение будет сильно напоминать паттерн Посетитель.

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

  1. Убедитесь, что у вас есть два класса с неудобными интерфейсами:

    • полезный сервис - служебный класс, который вы не можете изменять (он либо сторонний, либо от него зависит другой код);

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

  2. Опишите клиентский интерфейс, через который классы приложения смогли бы использовать сторонний класс.

  3. Создайте класс адаптера, реализовав этот интерфейс.

  4. Поместите в адаптер поле-ссылку на объект-сервис. В большинстве случаев, это поле заполняется объектом, переданным в конструктор адаптера. В случае простой адаптации этот объект можно передавать через параметры методов адаптера.

  5. Реализуйте все методы клиентского интерфейса в адаптере. Адаптер должен делегировать основную работу сервису.

  6. Приложение должно использовать адаптер только через клиентский интерфейс. Это позволит легко изменять и добавлять адаптеры в будущем.

Преимущества и недостатки

+ -
Отделяет и скрывает от клиента подробности преобразования различных интерфейсов. Усложняет код программы за счёт дополнительных классов.

Отношения с другими паттернами

  • Мост проектируют загодя, чтобы развивать большие части приложения отдельно друг от друга. Адаптер применяется постфактум, чтобы заставить несовместимые классы работать вместе.

  • Адаптер меняет интерфейс существующего объекта. Декоратор улучшает другой объект без изменения его интерфейса. Причём Декоратор поддерживает рекурсивную вложенность, чего не скажешь об Адаптере.

  • Адаптер предоставляет классу альтернативный интерфейс. Декоратор предоставляет расширенный интерфейс. Заместитель предоставляет тот же интерфейс.

  • Фасад задаёт новый интерфейс, тогда как Адаптер повторно использует старый. Адаптер оборачивает только один класс, а Фасад оборачивает целую подсистему. Кроме того, Адаптер позволяет двум существующим интерфейсам работать сообща, вместо того, чтобы задать полностью новый.

  • Мост, Стратегия и Состояние (а также слегка и Адаптер) имеют схожие структуры классов - все они построены на принципе «композиции», то есть делегирования работы другим объектам. Тем не менее, они отличаются тем, что решают разные проблемы. Помните, что паттерны - это не только рецепт построения кода определённым образом, но и описание проблем, которые привели к данному решению.