Описывается шаблон проектирования Адаптер или Adapter, приводится описание шаблона и пример его реализации.
Содержание
- Применение
- Реализация
- Итоги
Применение
Adapter — наименование шаблона прямо говорит о его назначении — обеспечить взаимодействие объектов с несовместимыми интерфейсами. Он полезен при интеграции сторонних библиотек и сервисов, при необходимости внедрить сторонний класс в существующую систему. Его также можно использовать для создания класса, который должен адаптировать внешние данные из заранее неизвестных источников.
Замечу, что существует два вида адаптеров: адаптер классов и адаптер объектов. Как правило, адаптер объектов содержит в себе ссылку на объект стороннего сервиса, при реализации адаптера классов наследуются интерфейсы как клиента, так и сервиса, поэтому потребности в ссылке на сервис зачастую нет.
Реализация
Исходные данные следующие.
Имеются клиент с устоявшимся интерфейсом и сервис, который реализует то, что требуется клиенту. Проблема в том, что интерфейс сервиса несовместим с клиентом. Можно, конечно, реализовать требуемый сервис с нужным интерфейсом, но проще адаптировать существующий к интерфейсу клиента.
Надеюсь, реализация этого шаблона ясна из описанного выше и, как вы догадываетесь, весьма сильно зависит от конкретной ситуации. Тем не менее приведу пример.
Определим интерфейс клиента.
<?php
interface IVehicle
{
public function drive(): string;
}
Далее создадим классы клиента, которые реализуют созданный интерфейс. Для наглядности в примере используются два класса.
<?php
class Car implements IVehicle
{
public function drive(): string
{
return "Drive by car";
}
}
class Bus implements IVehicle
{
public function drive(): string
{
return "Drive by bus";
}
}
Теперь создадим сторонний сервисный класс, который требуется клиенту. Его интерфейс отличается от клиентского.
<?php
class Bicycle
{
public function move(): string
{
return "A ride on the bicycle";
}
}
Создаём класс адаптера, который будет адаптировать сторонний сервис под запрос клиента. Для этого он получает ссылку на сторонний метод и использует его для формирования отклика клиенту.
<?php
class BicycleAdapter implements IVehicle
{
private Bicycle $bicycle;
public function __construct(Bicycle $bicycle)
{
$this->bicycle = $bicycle;
}
public function drive(): string
{
return $this->bicycle->move();
}
}
Ниже приведен фрагмент простенького кода, отображающего работу шаблона проектирования Адаптер.
<?php
require_once 'IVehicle.php';
require_once 'Car.php';
require_once 'Bus.php';
require_once 'Bicycle.php';
require_once 'BicycleAdapter.php';
// Функция, запрашивающая информацию у определенного сервиса
function getInfo(IVehicle $vehicle): void
{
echo '<br>' . $vehicle->drive();
}
$car = new Car();
$bus = new Bus();
$adapter = new BicycleAdapter(new Bicycle());
echo '<br><b>Отклик сервиса приложения</b>';
getInfo($car);
getInfo($bus);
echo '<br>============<br>';
echo '<b>Отклик стороннего сервиса</b>';
getInfo($adapter);
echo '<br>============<br>';
В итоге работы тестового кода будет следующий вывод.
Отклик сервиса приложения
I drive by car
I drive by bus
============
Отклик стороннего сервиса
A ride on the bicycle
============
Итоги
Сегодня был рассмотрен структурный шаблон проектирования Adapter, рассмотрены условия его применения. Теперь хотелось бы коротко перечислить достоинства и недостатки его применения.
Основные преимущества это:
- сохранение стороннего кода:
- разделение бизнес-логики и логики адаптации внешнего кода.
Недостатки стандартные несущественные, тем более в большинстве случаев выражены очень слабо:
- усложнение кода:
- некоторое падение производительности.
На этом всё. И моё традиционное.
Успехов в разработке!
Перейти к списку шаблонов проектирования.