Делегирование

Делегирование

Паттерн делегирования (англ. 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);