Адаптер (Adapter) — шаблон проектирования
20 января 2020
Шаблон предлагает прослойку в виде класса-адаптера для совместимости интегрируемого класса и пользовательского кода.
Далее приводится реализация паттерна на языке PHP. Скачать исходники (ZIP, 3 Кб)
Результат работы скрипта test_std_pay.php
Прочитав документацию ИнтПей, мы узнали, что для получения ссылки на оплату заказа в API есть метод pay_link.
Как вариант, для получения платёжной ссылки ИнтПей, мы можем прямо в клиентском коде написать обработку, которая отправляла бы запрос в API и обрабатывала результат. Но такой подход не гибок, потому что если нам понадобится получить платёжную ссылку где-то в другом месте проекта, то придётся снова писать отправку запроса в API, плодя дубли кода.
Другой вариант решения — создать класс-прослойку (адаптер), который будет содержать публичные методы, как у типового класса StdPaySystem и соответственно легко интегрироваться в клиентский код. Но при этом внутри себя адаптер будет работать с платёжной системой ИнтеПей, используя официальный класс IntPay.
Используя класс-адаптер IntPayAdapter, работа c ИнтПей стала такой же, как работа с типовой платёжной системой сайта.
Результат работы скрипта test_int_pay.php
Пример задачи: получение ссылки на страницу оплаты для разных платёжных систем.
Далее приводится реализация паттерна на языке PHP. Скачать исходники (ZIP, 3 Кб)

std_pay_system.class.php
Cодержит типовой класс StdPaySystem платёжной системы. У класса есть метод getLinkPay(), возвращающий ссылку на оплату заказа.<?
/**
* Стандартная платёжная система сайта
*/
class StdPaySystem
{
/**
* ID заказа на сайте
* @var int
*/
private $orderId;
/**
* Сумма заказа к оплате
* @var int
*/
private $paySum;
/**
* Конструктор объекта
* @param int $orderId - ID заказа
* @param int $paySum - сумма заказа к оплате
*/
public function __construct($orderId, $paySum)
{
$this->orderId = (int)$orderId;
$this->paySum = (int)$paySum;
}
/**
* Возвращает ссылку на оплату заказа
* @return string
*/
public function getLinkPay()
{
return 'https://test-payment-system1.ru/form-pay.html?order='.($this->orderId).'&sum='.($this->paySum);
}
}
?>
test_std_pay.php
Скрипт с клиентским кодом, в котором создаётся объект платёжной системы, задаются ID заказа и сумма к оплате, а затем происходит получение и вывод ссылки на оплату заказа.<?
//Стандартная платёжная система
require_once(__DIR__.'/std_pay_system.class.php');
$orderId = 1234567;
$orderSum = 1000;
$paySystem = new StdPaySystem($orderId, $orderSum);
$linkPay = $paySystem->getLinkPay();
echo $linkPay;
?>
Результат работы скрипта test_std_pay.php
https://test-payment-system1.ru/form-pay.html?order=1234567&sum=1000
int_pay.class.php
Содержит класс IntPay интегрируемой платёжной системы «ИнтПей». По легенде, это официальная PHP-библиотека от разработчиков системы и она не содержит отдельной функции для получения ссылки на оплату заказа. Но разработчики ведут документацию по API системы и предлагают через официальный класс посылать запросы в API, используя метод requestToAPI($method, $params=array()).<?
/**
* Платёжная система "ИнтПей" (тестовая интегрируемая платёжная система)
*/
class IntPay
{
/**
* Адрес API для отправки запросов
* @var string
*/
private static $urlAPI = 'https://api.test-intpay.ru';
/**
* Отправляет запрос в API
*
* @param string $method - символьный код функции сервиса
* @param array $params - массив с параметрами запроса
* @return array - вернёт массив c ответом
*/
public static function requestToAPI($method, $params=array())
{
//Приведение типов
if (is_array($params) == false) {
$params = array();
}
//Адрес запроса
$requestUrl = self::$urlAPI . '/'.$method.'/';
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $requestUrl);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_TIMEOUT, 10);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_AUTOREFERER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $params);
$response = curl_exec($curl);
curl_close($curl);
if ($response != '') {
$response = json_decode($response, true);
}
if (is_array($response) == false) {
$response = array();
}
return $response;
}
}
?>
Прочитав документацию ИнтПей, мы узнали, что для получения ссылки на оплату заказа в API есть метод pay_link.
Как вариант, для получения платёжной ссылки ИнтПей, мы можем прямо в клиентском коде написать обработку, которая отправляла бы запрос в API и обрабатывала результат. Но такой подход не гибок, потому что если нам понадобится получить платёжную ссылку где-то в другом месте проекта, то придётся снова писать отправку запроса в API, плодя дубли кода.
Другой вариант решения — создать класс-прослойку (адаптер), который будет содержать публичные методы, как у типового класса StdPaySystem и соответственно легко интегрироваться в клиентский код. Но при этом внутри себя адаптер будет работать с платёжной системой ИнтеПей, используя официальный класс IntPay.
int_pay_adapter.class.php
Содержит класс-прослойку IntPayAdapter. Для получения ссылки на оплату используется метод getLinkPay().<?
//Платёжная система IntPay
require_once(__DIR__.'/int_pay.class.php');
/**
* Класс-адаптер платёжной системы "ИнтПей"
*/
class IntPayAdapter
{
/**
* ID заказа на сайте
* @var int
*/
private $orderId;
/**
* Сумма заказа к оплате
* @var int
*/
private $paySum;
/**
* Конструктор объекта
* @param int $orderId - ID заказа
* @param int $paySum - сумма заказа к оплате
*/
public function __construct($orderId, $paySum)
{
$this->orderId = (int)$orderId;
$this->paySum = (int)$paySum;
}
/**
* Возвращает ссылку на оплату заказа
* @return string
*/
public function getLinkPay()
{
$response = IntPay::requestToAPI('pay_link', array(
'order_num' => $this->orderId,
'sum' => $this->paySum
));
if (is_array($response)) {
if (isset($response['url']) && $response['url'] != '') {
return $response['url'];
} else {
if (isset($response['error']) && $response['error'] != '') {
throw new Exception('Ошибка. При получении ссылки на оплату вернулась ошибка "'.$response['error'].'"');
} else {
throw new Exception('Ошибка. Не удалось получить ссылку на оплату');
}
}
} else {
throw new Exception('Ошибка. В ответ на запрос IntPay::requestToAPI пришёл не массив');
}
}
}
?>
test_int_pay.php
Скрипт клиентского кода, в котором создаётся объект платёжной системы ИнтПей, указываются ID заказа и сумма к оплате, затем через метод getLinkPay() происходит получение и вывод платёжной ссылки.Используя класс-адаптер IntPayAdapter, работа c ИнтПей стала такой же, как работа с типовой платёжной системой сайта.
<?
//Адаптер платёжной системы "Интпей"
require_once(__DIR__.'/int_pay_adapter.class.php');
$orderId = 1234567;
$orderSum = 1000;
$paySystem = new IntPayAdapter($orderId, $orderSum);
$linkPay = $paySystem->getLinkPay();
echo $linkPay;
?>
Результат работы скрипта test_int_pay.php
https://test-intpay.ru/pay.html?token=0fe65e4b0c7babf3cceff90b1e2f408b4e9ceee3