Статья
Шаблон проектирования "Цепочка обязанностей"

Шаблон проектирования "Цепочка обязанностей"

6 января 2019

Относится к поведенческим шаблонам.

По сути это набор обработчиков, которые по очереди получают запрос, а затем решают обрабатывать его или нет. Далее запрос передается дальше по цепочке.

Плюсы: уменьшаем зависимость между запросом и обработчиками.
Минусы: запрос может быть не обработан.
 

abstract class Logger
{
    /** @var int */
    public const DEBUG = 1;

    /** @var int */
    public const CRITICAL = 2;

    /** @var int */
    public const NOTICE = 4;

    /** @var array */
    protected $allowedPriorities = [];

    /** @var Logger|null */
    protected $next;

    /**
     * @param array $allowedPriorities
     */
    public function __construct(array $allowedPriorities = [])
    {
        $this->allowedPriorities = $allowedPriorities;
    }

    /**
     * @param string $message
     */
    abstract protected function writeMessage(string $message): void;

    /**
     * @param string $message
     * @param int    $priority
     */
    public function message(string $message, int $priority): void
    {
        if (in_array($priority, $this->allowedPriorities, true)) {
            $this->writeMessage($message);
        }

        if ($this->getNext() !== null) {
            $this->getNext()->message($message, $priority);
        }
    }

    /**
     * @param Logger $next
     */
    public function setNext(Logger $next): void
    {
        $this->next = $next;
    }

    /**
     * @return Logger|null
     */
    protected function getNext(): ?Logger
    {
        return $this->next;
    }
}

class ConsoleLogger extends Logger
{
    /**
     * @param string $message
     */
    protected function writeMessage(string $message): void
    {
        echo $message . PHP_EOL;
    }
}

class FileLogger extends Logger
{
    /**
     * @param string $message
     */
    protected function writeMessage(string $message): void
    {
        $f = fopen("error.log", "a");
        fwrite($f, $message . PHP_EOL);
        fclose($f);
    }
}

 

Использование:

$logger = new ConsoleLogger([Logger::NOTICE]);
$fileLogger = new FileLogger([Logger::CRITICAL, Logger::DEBUG]);

$logger->setNext($fileLogger);

$logger->message("Notice message", Logger::NOTICE);
$logger->message("Critical error", Logger::CRITICAL);



Источники:

http://designpatternsphp.readthedocs.io/ru/latest/Behavioral/ChainOfResponsibilities/README.html
https://habrahabr.ru/company/mailru/blog/325492/