Описывается шаблон проектирования Адаптер или Adapter, приводится описание шаблона и пример его реализации.
Наименование шаблона прямо говорит о назначении — обеспечить взаимодействие объектов с несовместимыми интерфейсами. Если оперировать общепринятыми терминами, то исходные данные следующие. Имеется некий клиент или приложение с устоявшимся интерфейсом взаимодействия и есть некоторый сервис, который реализует то, что нужно клиенту. Проблема в том, что интерфейс этого сервиса несовместим с нашим клиентом. Можно, конечно, реализовать требуемый сервис с нужным интерфейсом, но часто проще адаптировать существующий сервис к интерфейсу клиента.
Осуществляется это за счет создания обертки над сторонним сервисом и приведением его интерфейса или данных к нужному виду. Если детальнее, адаптер принимает запросы от клиента через клиентский интерфейс и направляет их сервису по интерфейсу, который тот понимает. Полученный ответ сервиса приводится к требованиям клиента и отправляется последнему. Как видите, все достаточно просто.
Замечу, что существует два вида адаптеров: адаптер классов и адаптер объектов, в чем разница, надеюсь, понятно. Тут можно добавить, что, как правило, адаптер объектов содержит в себе ссылку на объект стороннего сервиса, при реализации адаптера классов наследуются интерфейсы как клиента, так и сервиса, поэтому потребности в ссылке на сервис зачастую нет. Надеюсь, реализация этого шаблона ясна из описанного выше и весьма сильно зависит от конкретной ситуации. Тем не менее приведу пример.
//интерфейс клиента
interface IVehicle
{
function drive();
}
/*
Для наглядности приводится 2 класса, реализующие интерфейс некоего приложения
*/
// сервис1, реализующий интерфейс
class Car implements IVehicle
{
public drive() {
return "Drive by car";
}
}
// сервис2, реализующийй интерфейс
class Bus implements IVehicle
{
public drive() {
return "Drive by bus";
}
}
// сервис3 с другим интерфейсом, но который нужен приложению
class Bicycle
{
public move() {
return ("A ride on the bicycle");
}
}
// класс адаптера, преобразующий сторонний интерфейс к интерфейсу клиента
class DriveAdapter implements IVehicle
{
private $bicycle;
public _construct(Bicycle $bicycle)
{
$this->bicycle = $bicycle;
}
public drive()
{
return $this->bicycle->move();
}
}
Ниже приведен фрагмент простенького кода, отображающего работу шаблона проектирования Адаптер.
<?php
require 'IVehicle.php';
require 'Car.php';
require 'Bus.php';
require 'Bicycle.php';
require 'BicycleAdapter.php';
//функция, запрашивающая информацию у определенного сервиса
function getInfo(IVehicle $vehicle) {
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>';
?>
</body>
</html>
В итоге работы тестового кода будет следующий вывод.
Отклик сервиса приложения
I drive by car
I drive by bus
============
Отклик стороннего сервиса
A ride on the bicycle
============
Перейти к списку шаблонов проектирования.