В этой статье описывается шаблон проектирования PHP: адаптер адаптера. Для вашей справки приведем следующие сведения:
1. Обзор:
Изменение интерфейса-распространенная проблема, с которой программистам приходится мириться и справляться (хотя и неохотно). Поставщики программ изменяют свой код; изменяются системные библиотеки; развиваются и развиваются различные языки программирования и связанные с ними библиотеки.
Пример 1 : iPhone 4, вы можете использовать интерфейс UBS для подключения компьютера к зарядке. Если только у iPhone нет компьютера, что делать? Apple предоставляет адаптер питания для iPhone. Вы можете использовать этот адаптер питания для зарядки. Адаптер питания этого iPhone похож на режим адаптера, который мы его называем. (адаптер питания предназначен для изменения источника питания на требуемое напряжение, то есть функция адаптера состоит в том, чтобы сделать одну вещь подходящей для другой.)
Пример 2 : наиболее типичным примером является множество функциональных мобильных телефонов. Каждая модель имеет свои собственные подчиненные устройства. Однажды его собственное зарядное устройство сломалось, а на рынке такого зарядного устройства нет. Что мне делать? Универсальное зарядное устройство может решить эту проблему. Это универсальное зарядное устройство является адаптером.
2. Проблемы
Как избежать неудобств, вызванных изменениями API во внешних библиотеках? Если вы пишете библиотеку, можете ли вы предоставить способ, позволяющий существующим пользователям вашего программного обеспечения идеально обновляться, даже если вы изменили свой API? Как изменить интерфейс объекта, чтобы он лучше соответствовал вашим потребностям?
3. Решения
Шаблон адаптера обеспечивает совершенно другой интерфейс для объектов. Вы можете использовать адаптер для реализации общего интерфейса другого класса, избегая при этом споров, вызванных обновлением и разборкой кода клиента.
Шаблон адаптера преобразует интерфейс класса в другой интерфейс, ожидаемый клиентом. Шаблон адаптера позволяет двум классам, которые не могли работать вместе из-за несоответствия интерфейса (или несовместимости), работать вместе. Также известен как режим конвертера, режим трансформатора, режим оболочки (упакуйте некоторые существующие классы, чтобы они могли удовлетворять потребностям интерфейса). Подумайте, когда (не гипотетически! )Что происходит, когда меняется API сторонней библиотеки. В прошлом вам приходилось стискивать зубы, чтобы изменить весь код клиента, и ситуация была не такой простой. Возможно, вы работаете над новым проектом, в котором используются функции новой версии библиотеки, но у вас уже есть много старых приложений, которые хорошо взаимодействуют с предыдущими версиями библиотеки. Вы не сможете доказать ценность этих новых функций, если это обновление означает, что будет задействован код клиента для других приложений.
4. Классификация
Существует два типа шаблонов адаптеров: 1. Шаблон адаптера класса (реализован путем наследования); 2. Адаптер объекта (реализован с помощью композиции объектов)
1) Шаблон адаптера класса — адаптер наследует класс, который он реализует (как правило, множественное наследование).
Усыновитель и Усыновляемый являются наследственными отношениями
1. Сопоставьте с определенным классом адаптера и целью. В результате, когда мы хотим сопоставить класс и все его подклассы, адаптер класса не сможет выполнить задание 2. Это позволяет адаптеру переопределить часть поведения объекта адаптации, поскольку адаптер является подмножеством объекта адаптации 3. Вводится только объект, и для получения объекта адаптации не требуется дополнительного указателя.2) Шаблон адаптера объекта — адаптер содержит экземпляр класса, который он инкапсулирует. В этом случае адаптер вызывает физическую сущность обернутого объекта.
Адаптер и адаптер-это отношения делегирования
1. Позволяет одному адаптеру работать с несколькими адаптерами одновременно. Адаптер также может добавлять функции ко всем адаптерам сразу 2. Трудно использовать поведение переопределяющего адаптера, независимо от того, какой адаптер, его цель состоит в том, чтобы сохранить услуги, предоставляемые существующими классами, и предоставить интерфейсы клиентам, соответствующие их ожиданиям. Это означает предоставление новых интерфейсных услуг без изменения исходной системы.
Применимость 5
Режим адаптера используется, когда:
1. Вы хотите использовать существующий класс, но его интерфейс не соответствует вашим требованиям. 2. Вы хотите создать повторно используемый класс, который может работать с другими несвязанными или непредвиденными классами (то есть классами, интерфейсы которых могут быть несовместимы). 3 · (только адаптер объектов) вы хотите использовать некоторые существующие подклассы, но невозможно подклассировать каждый из них в соответствии с их интерфейсом. Адаптер объекта может адаптироваться к интерфейсу родительского класса. Другими словами, вводится только объект, и для косвенного получения адаптера не требуется никакого дополнительного указателя.
6. Структура
Адаптер класса использует множественное наследование для сопоставления одного интерфейса с другим, как показано на следующем рисунке:
Зависит от объекта, как показано на следующем рисунке:
7. Состав режима строительства
· цель: определяет доменные интерфейсы, используемые клиентом. · клиент: работает с объектами, которые соответствуют целевому интерфейсу. · – Адаптер: определяет интерфейс, который уже существует и использовался, который необходимо адаптировать. Адаптер: ядро шаблона адаптера. Он преобразует существующий интерфейс адаптированной Адаптированной роли в интерфейс соответствия целевой роли целевой роли. Интерфейс адаптера адаптирован к целевому интерфейсу
8. Эффект
Существуют различные компромиссы между адаптерами классов и адаптерами объектов.
Адаптер Класса
Сопоставьте адаптер и цель с определенным классом адаптера. В результате, когда мы хотим сопоставить класс и все его подклассы, адаптер класса не справится с этой задачей. Это позволяет адаптеру переопределить часть поведения объекта адаптации, поскольку адаптер является подклассом объекта адаптации. · вводится только один объект, и для косвенного получения объекта адаптации не требуется никакого дополнительного указателя.
Адаптер объекта
Позвольте адаптеру работать с несколькими адаптерами – то есть с самим адаптером и всеми его подклассами (если таковые имеются) – одновременно. Адаптер также может добавлять функции ко всем адаптерам одновременно. Это затрудняет переопределение поведения адаптера. Для этого необходимо создать подкласс адаптера и заставить адаптер ссылаться на этот подкласс, а не на сам адаптер.
Некоторые другие факторы, которые следует учитывать при использовании режима адаптера, включают:
1) Степень соответствия адаптера рабочая нагрузка по сопоставлению интерфейса получателя с интерфейсом цели может отличаться для каждого адаптера. Объем работ может варьироваться от простых преобразований интерфейса (таких как изменение имени операции) до поддержки совершенно другого набора операций. Рабочая нагрузка адаптера зависит от сходства между целевым интерфейсом и адаптивным интерфейсом 2) Подключаемый адаптер когда другие классы используют класс, тем меньше требуется допущений, тем более многоразовым является класс. Если вы создаете соответствие интерфейса как класс, нет необходимости предполагать, что тот же интерфейс виден другим классам. Другими словами, сопоставление интерфейсов позволяет нам добавлять наши собственные классы в некоторые существующие системы, эти системы могут иметь разные интерфейсы для этого класса. 3) Потенциальная проблема с использованием адаптеров заключается в том, что они не являются прозрачными для всех клиентов. Адаптированный объект больше не совместим с интерфейсом адаптера, поэтому не все адаптеры
9. Реализация
Адаптеры классов используют наследование
Давайте рассмотрим, как защитить приложение от воздействия при изменении API.
Цель ясно дала понять, что метод hello () будет улучшен в будущих версиях, даже если он не будет поддерживаться или устранен. Далее, давайте предположим, что выпущена вторая версия target. Новый метод green () заменяет hello().
Если мы продолжим использовать исходный код клиента, мы обязательно сообщим об ошибке и не сможем найти метод Hello.
Решение для “обновления” API заключается в создании адаптера.
Адаптер класса использует наследование:
'; } /** *Adding new methods */ public function greet() { echo ' Greet '; } } /** *Class adapter role */ class Adapter extends Adaptee implements Target { /** *There is no world method in the source class */ public function hello() { parent::greet(); } } /** *Client program * */ class Client { /** * Main program. */ public static function main() { $adapter = new Adapter(); $adapter->hello(); $adapter->world(); } } Client::main(); ?>
Адаптер объекта использует делегирование
'; } /** *Adding new methods */ public function greet() { echo ' Greet '; } } /** *Class adapter role */ class Adapter implements Target { private $_adaptee; /** * construct * * @param Adaptee $adaptee */ public function __construct(Adaptee $adaptee) { $this->_adaptee = $adaptee; } /** *There is no world method in the source class */ public function hello() { $this->_adaptee->greet(); } /** *There is no world method in the source class */ public function world() { $this->_adaptee->world(); } } /** *Client program * */ class Client { /** * Main program. */ public static function main() { $adaptee = new Adaptee(); $adapter = new Adapter($adaptee); $adapter->hello(); $adapter->world(); } } Client::main(); ?>
Как показывает код в примере, вы можете использовать шаблон адаптера, чтобы избежать неудобств, связанных с изменениями внешней библиотеки, если она совместима. Как разработчик библиотеки, вы должны самостоятельно написать адаптер, чтобы облегчить пользователям использование новой версии библиотеки без изменения всего существующего кода.
Шаблон адаптера, предложенный в книге GoF, имеет тенденцию использовать наследование, а не композицию. Это выгодно в строго типизированных языках, поскольку адаптер фактически является подклассом целевого класса и, следовательно, может лучше сочетаться с методами в классе.
Для большей гибкости я предпочитаю методы композиции (особенно в сочетании с инверсией зависимостей); однако унаследованные методы предоставляют две версии интерфейса, что может быть ключом к повышению гибкости в вашем практическом применении.
10. Режим адаптера и другие связанные с ним режимы
Режим моста: Шаблон моста аналогичен объектному адаптеру, но начальная точка шаблона моста отличается: цель шаблона моста состоит в том, чтобы отделить часть интерфейса от части реализации, чтобы их можно было легко и относительно независимо изменять. Шаблон адаптера объекта означает изменение интерфейса существующего объекта
Шаблон декоратора: режим декоратора расширяет функциональность других объектов без изменения их интерфейсов. Таким образом, режим оформления более прозрачен для приложения, чем адаптер. В результате шаблон декоратора поддерживает рекурсивную композицию, что невозможно только с адаптерами.
Фасад: В центре внимания шаблона адаптера находится изменение API одного класса. Цель фасада состоит в том, чтобы обеспечить более лаконичный интерфейс для всей подсистемы, состоящей из множества объектов. Шаблон адаптера инкапсулирует отдельный класс. Шаблон адаптера часто используется, когда для совместной работы требуется сторонний API, пытающийся изолировать ваш код от сторонней библиотеки.
Как режим адаптера, так и режим внешнего вида являются инкапсуляцией существующей системы. Но намерения этих двух режимов совершенно разные. Первый позволяет существующей системе работать с проектируемой системой, в то время как второй обеспечивает более удобный интерфейс доступа для существующей системы. Проще говоря, шаблон адаптера разрабатывается постфактум, в то время как режим внешнего вида должен быть разработан заранее, потому что система зависит от внешнего вида. Короче говоря, шаблон адаптера не вводит новый интерфейс, в то время как шаблон фасада определяет совершенно новый интерфейс.
Режим прокси Прокси определяется для другого объекта без изменения его интерфейса.
Различия между режимом декоратора, режимом адаптера и режимом внешнего вида заключаются в следующем
В режиме декоратора он не будет изменять интерфейс, а будет украшать интерфейс один за другим, то есть добавлять новые функции.
Шаблон адаптера заключается в косвенном преобразовании одного интерфейса в другой посредством адаптации.
Режим внешнего вида, в основном, предназначен для обеспечения чистого и согласованного интерфейса для клиента.
Подробнее о содержании, связанном с PHP заинтересованные читатели могут ознакомиться с этой темой сайта: “Вводный учебник по объектно-ориентированному программированию PHP”, “Навыки работы с массивом PHP (массивом)”, “Вводный курс по основному синтаксису PHP”, “Краткое описание операций PHP и использования операторов”, “Краткое описание использования символьной строки (строки) PHP”, “Учебник по введению в работу с базой данных PHP + MySQL” и “Общие навыки работы с базой данных PHP”.
Я надеюсь, что эта статья поможет вам в программировании на PHP.