Преобразует интерфейс класса к другому интерфейсу, на который рассчитан клиент. Обеспечивает совместную работу классов, невозможную в обычных условиях из-за несовместимости интерфейсов.
-
Когда вы хотите использовать сторонний класс, но его интерфейс не соответствует остальному коду приложения.
- Адаптер позволяет создать объект-прокладку, который будет превращать вызовы приложения в формат, понятный стороннему классу.
-
Когда вам нужно использовать несколько существующих подклассов, но в них не хватает какой-то общей функциональности. Причём расширять суперкласс вы не можете (Похоже на Декоратор).
-
Вы могли бы создать ещё один уровень подклассов, и добавить в них недостающую функциональность. Но при этом придётся дублировать один и тот же код в обеих ветках подклассов.
Более элегантное решение - поместить недостающую функциональность в адаптер и приспособить его для работы с суперклассом. Такой адаптер сможет работать со всеми подклассами иерархии. Это решение будет сильно напоминать паттерн Посетитель.
-
-
Убедитесь, что у вас есть два класса с неудобными интерфейсами:
-
полезный сервис - служебный класс, который вы не можете изменять (он либо сторонний, либо от него зависит другой код);
-
один или несколько клиентов - классов приложения, несовместимых с сервисом из-за неудобного или несовпадающего интерфейса.
-
-
Опишите клиентский интерфейс, через который классы приложения смогли бы использовать сторонний класс.
-
Создайте класс адаптера, реализовав этот интерфейс.
-
Поместите в адаптер поле-ссылку на объект-сервис. В большинстве случаев, это поле заполняется объектом, переданным в конструктор адаптера. В случае простой адаптации этот объект можно передавать через параметры методов адаптера.
-
Реализуйте все методы клиентского интерфейса в адаптере. Адаптер должен делегировать основную работу сервису.
-
Приложение должно использовать адаптер только через клиентский интерфейс. Это позволит легко изменять и добавлять адаптеры в будущем.
+ | - |
---|---|
Отделяет и скрывает от клиента подробности преобразования различных интерфейсов. | Усложняет код программы за счёт дополнительных классов. |
-
Мост проектируют загодя, чтобы развивать большие части приложения отдельно друг от друга. Адаптер применяется постфактум, чтобы заставить несовместимые классы работать вместе.
-
Адаптер меняет интерфейс существующего объекта. Декоратор улучшает другой объект без изменения его интерфейса. Причём Декоратор поддерживает рекурсивную вложенность, чего не скажешь об Адаптере.
-
Адаптер предоставляет классу альтернативный интерфейс. Декоратор предоставляет расширенный интерфейс. Заместитель предоставляет тот же интерфейс.
-
Фасад задаёт новый интерфейс, тогда как Адаптер повторно использует старый. Адаптер оборачивает только один класс, а Фасад оборачивает целую подсистему. Кроме того, Адаптер позволяет двум существующим интерфейсам работать сообща, вместо того, чтобы задать полностью новый.
-
Мост, Стратегия и Состояние (а также слегка и Адаптер) имеют схожие структуры классов - все они построены на принципе «композиции», то есть делегирования работы другим объектам. Тем не менее, они отличаются тем, что решают разные проблемы. Помните, что паттерны - это не только рецепт построения кода определённым образом, но и описание проблем, которые привели к данному решению.