Шаблон проектирования «Адаптер»
Предыдущий материал из этой серии вы можете прочитать здесь.
В этой статье мы продолжаем разбирать шаблоны проектирования, и сегодня наша цель - шаблон под названием "Адаптер".
Этот шаблон проектирования разумно использовать в том случае, если ваш код зависит от некоего внешнего API, либо от класса, который, предположительно, будет часто меняться.
Данный шаблон относится к категории структурных так как показывает нам, как стоит организовать наш код и классы так, чтобы потом можно было легко с ними управляться.
И снова отмечу тот факт, что шаблоны проектирования не несут в себе ничего нового по сравнению с обычными классами. Они просто показывают нам, как структурировать наши классы, обрабатывать их поведение и управлять их созданием.
Проблема
<?php class PayPal { public function __construct() { // здесь ваш код // } public function sendPayment($amount) { // оплата через PayPal // echo "Оплата через PayPal: ". $amount; } } $paypal = new PayPal(); $paypal->sendPayment('2629');
В коде выше мы видим инициализацию класса PayPal для оплаты некой суммы. Здесь мы непосредственно создаем экземпляр класса PayPal и производим оплату.
Данный код должен использоваться в нескольких местах, и мы применяем для проведения оплаты такую конструкцию:
$paypal->sendPayment('сумма');
Некоторое время назад в PayPal изменили имя метода с SendPayment на payAmount. Это ясно дает нам понять суть проблемы, ведь мы пока используем старый метод.
Теперь нам нужно заменить все вызовы метода SendPayment на payAmount. Представьте, сколько кода нам нужно будет поменять и сколько времени потратить на повторное тестирование.
Решение
Одно из решений этой задачи - использование шаблона проектирования "Адаптор".
Википедия гласит:
"Адаптер" - шаблон проектирования, который делает возможным использование интерфейса существующего класса из другого интерфейса. Часто он используется для того, чтобы заставить уже имеющиеся классы работать с другими классами без модификации их кода.
— Регулярная проверка качества ссылок по более чем 100 показателям и ежедневный пересчет показателей качества проекта.
— Все известные форматы ссылок: арендные ссылки, вечные ссылки, публикации (упоминания, мнения, отзывы, статьи, пресс-релизы).
— SeoHammer покажет, где рост или падение, а также запросы, на которые нужно обратить внимание.
SeoHammer еще предоставляет технологию Буст, она ускоряет продвижение в десятки раз, а первые результаты появляются уже в течение первых 7 дней. Зарегистрироваться и Начать продвижение
Для этого нам нужно создать интерфейс-оболочку, которая сделает это возможным. Мы не будем вносить никаких изменений во внешнюю библиотеку т.к. попросту не имеем к ней доступа, и она может меняться без нашего ведома в любое время.
Давайте посмотрим на код, показывающий работу шаблона в действии:
// Неизменный класс PayPal class PayPal { public function __construct() { // здесь ваш код // } public function sendPayment($amount) { // оплата через PayPal // echo "Оплата через PayPal: ". $amount; } } // простой интерфейс для всех создаваемых Адаптеров interface paymentAdapter { public function pay($amount); } class paypalAdapter implements paymentAdapter { private $paypal; public function __construct(PayPal $paypal) { $this->paypal = $paypal; } public function pay($amount) { $this->paypal->sendPayment($amount); } }
Посмотрите на код выше и заметите, что в код класса PayPal не было внесено изменений. Вместо этого мы создали один интерфейс для нашего платежного Адаптера и класс Адаптера для PayPal.
И далее мы уже работаем с объектом класса-Адаптера вместо того, чтобы использовать непосредственно класс PayPal.
В процессе создания объекта из класса-Адаптера мы передаем ему в качестве аргумента основной неизменяемый класс PayPal для того, чтобы класс-Адаптер мог иметь ссылку на главный класс и мог вызывать методы этого класса.
Применяем мы это следующим образом:
// клиентский код $paypal = new paypalAdapter(new PayPal()); $paypal->pay('2629');
Теперь представьте, что PayPal меняет имя метода с sendPayment на payAmount. Теперь нам нужно всего лишь внести изменения в класс paypalAdapter. Давайте посмотрим на измененный код Адаптера, в котором есть лишь одна правка:
class paypalAdapter implements paymentAdapter { private $paypal; public function __construct(PayPal $paypal) { $this->paypal = $paypal; } public function pay($amount) { $this->paypal->payAmount($amount); } }
Вот так просто. Всего одно изменение.
Добавление нового Адаптера
Теперь, когда мы разобрались с общей идеей, очень просто добавить зависимость нового класса от уже существующего адаптера paymentAdapter.
Пусть, у нас есть еще вариант оплаты с помощью MoneyBooker.
Как и в предыдущем случае, мы не будем напрямую использовать класс MoneyBooker, а воспользуемся тем же адаптером, что и в случае с PayPal.
// Неизменный класс MoneyBooker class MoneyBooker { public function __construct() { // ваш код здесь // } public function doPayment($amount) { // оплата через MoneyBooker // echo "Оплата через MoneyBooker: ". $amount; } } // MoneyBooker-Адаптор class moneybookerAdapter implements paymentAdapter { private $moneybooker; public function __construct(MoneyBooker $moneybooker) { $this->moneybooker = $moneybooker; } public function pay($amount) { $this->moneybooker->doPayment($amount); } } // Клиентский код $moneybooker = new moneybookerAdapter(new MoneyBooker()); $moneybooker->pay('2629');
Как видите, работает все тот же принцип. Вы определяете метод, доступный для стороннего класса и, затем, если происходят изменения во внешнем API, вы просто меняете зависимый класс без вмешательства в его интерфейс.
Вывод
Хорошее функциональное приложение практически всегда связано с внешними библиотеками и API. Используйте шаблон проектирования "Адаптер" для того, чтобы минимизировать свою работу при изменении кода в любых неподвластных вам библиотеках и API.
Понравился материал и хотите отблагодарить?
Просто поделитесь с друзьями и коллегами!
Смотрите также:
PHP: Получение информации об объекте или классе, методах, свойствах и наследовании |
|
Функции обратного вызова, анонимные функции и механизм замыканий Сервис онлайн-записи на собственном Telegram-боте
Попробуйте сервис онлайн-записи VisitTime на основе вашего собственного Telegram-бота:— Разгрузит мастера, специалиста или компанию; — Позволит гибко управлять расписанием и загрузкой; — Разошлет оповещения о новых услугах или акциях; — Позволит принять оплату на карту/кошелек/счет; — Позволит записываться на групповые и персональные посещения; — Поможет получить от клиента отзывы о визите к вам; — Включает в себя сервис чаевых. Для новых пользователей первый месяц бесплатно. Зарегистрироваться в сервисе |
|
Деструктор и копирование объектов с помощью метода __clone() |
|
Эволюция веб-разработчика или Почему фреймворк - это хорошо? |
|
Магические методы в PHP или методы-перехватчики (сеттеры, геттеры и др.) |
|
50 классных сервисов, программ и сайтов для веб-разработчиков |