Мастер PHP | Практические аспекты шаблона адаптера

  1. Что такое шаблон адаптера?
  2. Понимание реализации шаблона адаптера
  3. Кто разрабатывает класс адаптера?
  4. Шаблон адаптера - неправильный путь
  5. Шаблон адаптера - правильный путь
  6. Резюме

Разработка программного обеспечения совершенствуется каждый день благодаря новым концепциям, методологиям и высококачественным библиотекам и инфраструктурам. Но даже со всеми этими улучшениями мы не можем предотвратить изменения в разработке программного обеспечения. Вы можете подумать, что ваша система разработана с учетом всех ее требований, но всегда будет запрос на изменение, который разрушит ваш идеальный дизайн. Мы должны быть готовы ко всем возможным изменениям как разработчики.

Шаблон Adapter - это шаблон проектирования, который обычно используется для управления изменениями в разработке. В этой статье мы рассмотрим использование и преимущества шаблонов, используемых в реальных приложениях.

Что такое шаблон адаптера?

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

Предположим, у нас есть мобильный телефон, который используется для доступа к учетной записи электронной почты для отправки писем. Приложение телефона и электронной почты действуют как отдельные компоненты, которые подключаются через Интернет.

Приложение телефона и электронной почты действуют как отдельные компоненты, которые подключаются через Интернет

Теперь предположим, что мы путешествуем в место, где интернет-соединение недоступно для телефона. Как нам получить доступ к электронной почте в этой ситуации? Нам нужен адаптер, который соединяет наш мобильный телефон с приложением электронной почты. Давайте посмотрим на функции, ожидаемые от такого адаптера:

  • Включите интернет-соединение между мобильным телефоном и почтовым приложением.
  • Доступ к API электронной почты для отправки электронной почты.

Учитывая требования, мы можем выбрать IFTTT в качестве адаптера. IFTTT - это сервис, который поддерживает автоматизацию задач с помощью популярных API. Таким образом, мы можем использовать IFTTT в качестве адаптера, как показано на рисунке ниже.

В этом решении мы отправляем SMS-сообщение в службу IFTTT, содержащее текст сообщения. Для отправки SMS на международный номер не требуется подключение к Интернету. Затем служба IFTTT получает содержимое сообщения и инициализирует рецепт (рецепты должны быть предварительно настроены), чтобы отправить электронное письмо с помощью API почтового приложения.

IFTTT имеет доступ к API электронной почты, а также к интернет-соединению с приложением электронной почты, выполняя оба требования, ожидаемые от адаптера. IFTTT выступает в роли адаптера для интеграции нашего приложения для телефона и электронной почты, которое находилось в несовместимом состоянии из-за недоступности Интернета.

Я думаю, что к настоящему времени у вас должно быть четкое понимание функциональности шаблона адаптера в реальном мире. Прежде чем мы перейдем к реализации, давайте посмотрим на определение шаблона как предоставлено Википедией :

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

Понимание реализации шаблона адаптера

Было бы идеально использовать практический сценарий для понимания процесса и компонентов шаблона адаптера, поэтому предположим, что у нас есть общий интерфейс для подписок по электронной почте для нашего веб-сайта. Следующий код содержит реализацию интерфейса подписки на электронную почту.

<? php interface EmailSubscribe {public function subscribe ($ email); публичная функция отписаться ($ email); публичная функция sendUpdates (); }

Разработчики и поставщики услуг электронной почты могут реализовать этот интерфейс для предоставления классов подписки электронной почты для каждого из поставщиков электронной почты, таких как Feedburner, Mailchimp и т. Д. Следующий код содержит пример реализации для одной службы и инициализации метода sendUpdates ().

<? php class FeedburnerEmail реализует EmailSubscribe {публичная функция подписки ($ email) {} публичная функция отписаться ($ email) {} публичная функция sendUpdates () {// Получить доступных подписчиков // Получить обновления сайта // Отправить электронную почту}} $ feedburner_email = новый FeedburnerEmail (); $ Feedburner_email-> sendUpdates ();

Теперь предположим, что Feedburner решает изменить свою библиотеку на последнюю версию.

<? php class FeedburnerEmailVersion2 {открытая функция subscribe ($ email) {} открытая функция unsubscribe ($ email) {} открытая функция getSubscribeers () {// Возврат подписчиков} открытая функция sendEmails ($ подписчики) {// Получить обновления сайта // Send Emails echo "электронные письма, отправленные сегодня"; }} $ feedburner_email = new FeedburnerEmailVersion2 (); $ подписчики = $ feedburner_email-> getSubscribeers (); $ Feedburner_email-> sendEmails ($ абонентов);

Согласно предыдущему коду, добавляются новые методы, а существующая функциональность изменяется в новой версии библиотеки. Код инициализации изменился, и последняя версия Feedburner стала несовместимой с интерфейсом EmailSubscribe.

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

<? php class FeedburnerAdapter реализует EmailSubscribe {public function subscribe ($ email) {} public function unsubscribe ($ email) {} public function sendUpdates () {$ feedburner = new FeedburnerEmailVersion2 (); $ подписчики = $ feedburner-> getSubscribeers (); $ Feedburner-> sendEmails ($ абонентов); }} $ feedburner_email = new FeedburnerAdapter (); $ Feedburner_email-> sendUpdates ();

Адаптер FeedburnerAdapter инициализирует библиотеку электронной почты Feedburner в своем методе sendUpdates () и восстанавливает предыдущую реализацию, вызывая новые методы в последней версии библиотеки. Теперь наше приложение и библиотека Feedburner взаимодействуют через стандартный интерфейс FeedburnerAdapter. Наше приложение не знает, что реализация изменилась, и вместо исходного библиотечного класса работает адаптер. Разработчики могут вызывать стандартный набор методов, не внося никаких изменений в свой исходный код.

Теперь пришло время понять теоретические аспекты паттерна Adapter, используя его диаграмму классов.

Обычно в нашем приложении есть Client, Target и Adaptee, а класс Adaptee реализует интерфейс Target. В ситуациях, когда Client и Adaptee становятся несовместимыми, мы создаем новый класс с именем Adapter и помещаем его между Target и Adaptee для обеспечения совместимости компонентов друг с другом.

Диаграмма выше содержит оригинальный дизайн шаблона Adapter для использования в лучших сценариях. Интерфейсы не используются широко в проектах PHP, но это не означает, что вы не можете использовать шаблон адаптера. Пока некоторый компонент объединяет несовместимые интерфейсы, его можно считать адаптером.

В моем последняя статья на Opauth мы обсудили использование класса стратегии в библиотеке Opauth. Он также действует как адаптер, даже если он не реализует никаких интерфейсов. Адаптер стратегии сделал открытые библиотеки аутентификации совместимыми с базовой библиотекой Opauth.

Кто разрабатывает класс адаптера?

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

Шаблон адаптера - неправильный путь

Многие опытные разработчики считают, что шаблон Adapter используется для исправления плохо спроектированных систем. В зависимости от ситуации нам, возможно, придется согласиться с этим. Но давайте рассмотрим слегка измененную версию примера подписки по электронной почте, который мы обсуждали ранее.

Предположим, что две команды были назначены для разработки классов Feedburner и Mailchimp по отдельности на основе исходного интерфейса, который мы использовали ранее.

<? php класс FeedburnerEmail реализует EmailSubscribe {публичная функция подписки ($ email) {} публичная функция отписаться ($ email) {} публичная функция getSubscribeers () {// возвращает список подписчиков} публичная функция sendUpdates () {$ this-> getSubscribeers (); // Получение обновлений веб-сайта // Отправка электронной почты}} <? Php class MailchimpEmail реализует EmailSubscribe {public $ подписчиков; публичная функция подписки ($ email) {} публичная функция отписки ($ email) {} публичная функция getSubscribeers () {$ this-> подписчики = "Список подписчиков"; } публичная функция sendUpdates () {$ подписчики = $ это-> подписчики; // Получаем обновления сайта // Отправляем электронные письма}}

Хотя оба класса совместимы с целевым интерфейсом, между клиентом и этими двумя классами существует несовместимость. Рассмотрим код инициализации, чтобы лучше это понять:

<? php $ email = FeedburnerEmail (); $ Email-> sendUpdates (); $ email = MailchimpEmail (); $ Email-> getSubscribers (); $ Email-> sendUpdates ();

Код из Team 2 не совпадает с кодом инициализации клиента и, следовательно, становится несовместимым. Нам нужен адаптер, чтобы исправить проблему для класса Mailchimp. Это считается неправильным использованием шаблона адаптера, поскольку мы могли бы спланировать интерфейс должным образом, чтобы избежать таких проблем несовместимости.

Шаблон адаптера - правильный путь

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

Почтовые подписки отлично работают на нашем сайте. В связи с успехом подписок, руководство планирует внедрить подписки Twitter для сайта. В настоящее время, когда пользователь подписывается по электронной почте, он или она получает уведомления по электронной почте об обновлениях содержимого веб-сайта. С новым требованием, в основном пользователь подписывается, аутентифицируя свою учетную запись Twitter для нашего сайта. Каждый раз, когда сайт обновляется, в его твиттере об обновлении будут создаваться новые твиты.

Следующий код содержит библиотеку Twitter для этой реализации.

<? php class TwitterService {public function authenticate ($ username) {} публичная функция deauthenticate ($ username) {} публичная функция tweet ($ message, $ user) {// Обновление стены новым твитом} публичная функция getUpdates () {/ / Return Updates} публичная функция getFollowers () {// Возврат подписчиков}}

Мы не можем сделать TwitterService совместимым с целевым интерфейсом или клиентом с его оригинальной реализацией. Но мы можем видеть, что логика класса похожа на EmailSubscription. Следовательно, в этой ситуации мы можем эффективно использовать класс адаптера, чтобы сделать TwitterService совместимым с клиентом без изменения клиентского кода.

Давайте посмотрим на реализацию класса TwitterAdapter.

<? php class В TwitterAdapter реализована функция EmailSubscribe {public function subscribe ($ username) {} public function unsubscribe ($ username) {} public function sendUpdates () {$ tw_service = new TwitterService (); $ updates = $ tw_service-> getUpdates (); $ подписчики = $ tw_service-> getFollowers (); $ tw_service-> Tweet ($ обновления, $ абонентов); }} $ twitter_subscribe = new TwitterAdapter (); $ Twitter_subscribe-> sendUpdates ();

Класс TwitterAdapter реализует наш целевой интерфейс с оригинальными функциями, связанными с подпиской на электронную почту. Внутренне он создает объект TwitterService и делает функцию твита совместимой с sendUpdates (), вызывая необходимые функции и возвращая выходные данные, ожидаемые клиентом.

Код инициализации кажется похожим на предыдущий код. Поэтому клиентский класс не знает, что сервис Twitter отправляет твит вместо обновлений по электронной почте. Класс клиента продолжает вызывать метод sendUpdate () для всех сервисов, и соответствующие методы обновления будут выполняться через адаптеры.

Резюме

В этой статье мы рассмотрели шаблон адаптера и попытались понять его эффективное использование на нескольких практических примерах. Мы узнали, что существует и хорошее, и плохое использование шаблона адаптера, и теперь вам решать, когда использовать адаптеры.

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

Изображение через Fotolia

Что такое шаблон адаптера?
Что такое шаблон адаптера?
Как нам получить доступ к электронной почте в этой ситуации?
Lt;?
Lt;?
Lt;?
Lt;?
Кто разрабатывает класс адаптера?
Lt;?
Lt;?