Паттерн делегирования (англ. delegation pattern) — это способ, которым объект внешне выражает некоторое поведение, но в реальности передаёт ответственность за выполнение этого поведения связанному объекту. Шаблон делегирования является фундаментальной абстракцией, которая поддерживает композицию (также называемую агрегацией), примеси (mixins) и аспекты (aspects).
Цель
Возможность изменить поведение конкретного экземпляра объекта вместо создания нового класса путем наследования.
Минусы
Этот шаблон обычно затрудняет оптимизацию по скорости в пользу улучшенной чистоты абстракции.
Пример реализации паттерна делегирования на PHP
Рассмотрим на примере менеджера отправки SMS и Email.
Менеджер отправки сообщений
class AppMessenger implements MessengerInterface
{
private MessengerInterface $messenger;
public function __construct()
{
$this->toEmail();
}
/**
* @return $this
*/
public function toEmail()
{
$this->messenger = new EmailMessenger();
return $this;
}
/**
* @return $this
*/
public function toSms()
{
$this->messenger = new SmsMessenger();
return $this;
}
/**
* @param $value
* @return MessengerInterface
*/
public function setSender($value): MessengerInterface
{
return $this->messenger->setSender($value);
}
/**
* @param $value
* @return MessengerInterface
*/
public function setRecipient($value): MessengerInterface
{
return $this->messenger->setRecipient($value);
}
/**
* @param $value
* @return MessengerInterface
*/
public function setMessage($value): MessengerInterface
{
return $this->messenger->setMessage($value);
}
/**
* @return bool
*/
public function send(): bool
{
return $this->messenger->send();
}
}
Абстрактный мессенджер
abstract class AbstractMessenger implements MessengerInterface
{
/**
* @var string
*/
protected string $sender;
/**
* @var string
*/
protected string $recipient;
/**
* @var string
*/
protected string $message;
/**
* @param $value
* @return MessengerInterface
*/
public function setSender($value): MessengerInterface
{
$this->sender = $value;
return $this;
}
/**
* @param $value
* @return MessengerInterface
*/
public function setRecipient($value): MessengerInterface
{
$this->recipient = $value;
return $this;
}
/**
* @param $value
* @return MessengerInterface
*/
public function setMessage($value): MessengerInterface
{
$this->message = $value;
return $this;
}
/**
* @return bool
*/
public function send(): bool
{
return true;
}
}
Мессенджер Email
class EmailMessenger extends AbstractMessenger
{
/**
* @return bool
*/
public function send(): bool
{
\Debugbar::info('Sent by ' . __CLASS__);
return parent::send();
}
}
Мессенджер SMS
class SmsMessenger extends AbstractMessenger
{
/**
* @return bool
*/
public function send(): bool
{
\Debugbar::info('Sent by ' . __METHOD__);
return parent::send();
}
}
Пример использования
$appMessenger = new AppMessenger();
$appMessenger
->toEmail() // переключаемся на отправку писем
->setSender('111111111111')
->setRecipient('info@support.com')
->setMessage('Hello')
->send();
\DebugBar::info($appMessenger);
$appMessenger
->toSms() // переключаемся на отправку SMS
->setRecipient('222222222222')
->setMessage('Hello')
->send();
\DebugBar::info($appMessenger);