Chain of Responsibility

Шаблон проектирования Chain of Responsibility («цепочка обязанностей») — один из поведенческих паттернов, предназначенный для организации обработки запросов таким образом, чтобы каждый объект мог либо обработать запрос самостоятельно, либо передать его следующему звену цепочки. Основная цель этого паттерна заключается в уменьшении зависимости между отправителем запроса и обработчиком запроса, делая систему более гибкой и расширяемой.

Основные элементы паттерна

  • Handler: Абстрактный класс или интерфейс, определяющий метод обработки запроса (handle()). Реализует механизм передачи запроса следующему элементу цепи.
  • Concrete Handler: Конкретная реализация обработчика, способная обрабатывать определённые типы запросов. Если запрос не подходит, передаёт его дальше по цепочке.
  • Client: Отправляет запросы в начало цепочки и ожидает результата.

Пример реализации на PHP

// Интерфейс обработчика
interface Handler {
    public function setNext(Handler $handler): void;
    public function handle($request): ?string;
}

abstract class AbstractHandler implements Handler {
    private $nextHandler;
    
    // Метод установки следующего обработчика в цепочке
    public function setNext(Handler $handler): void {
        $this->nextHandler = $handler;
    }
    
    // Основной метод обработки запроса
    public function handle($request): ?string {
        if ($this->canHandle($request)) {
            return $this->processRequest($request);
        }
        
        if ($this->nextHandler !== null) {
            return $this->nextHandler->handle($request); // Передача далее по цепочке
        }
        
        return null;
    }
    
    abstract protected function canHandle($request): bool;
    abstract protected function processRequest($request): string;
}

class FirstHandler extends AbstractHandler {
    protected function canHandle($request): bool {
        return $request === 'first';
    }
    
    protected function processRequest($request): string {
        return "First handler processed request";
    }
}

class SecondHandler extends AbstractHandler {
    protected function canHandle($request): bool {
        return $request === 'second';
    }
    
    protected function processRequest($request): string {
        return "Second handler processed request";
    }
}

// Клиентская логика
$firstHandler = new FirstHandler();
$secondHandler = new SecondHandler();

$firstHandler->setNext($secondHandler);

echo $firstHandler->handle('first'); // Выведет: First handler processed request
echo "\n";
echo $firstHandler->handle('second'); // Выведет: Second handler processed request

Преимущества и недостатки

Преимущества:

  • Уменьшение связи между клиентом и обработчиками, поскольку клиент взаимодействует только с первым элементом цепочки.
  • Легкость добавления новых обработчиков путём расширения абстрактного класса.
  • Возможность изменения порядка обработки запросов динамически во время выполнения программы.

Недостатки:

  • Потеря контроля над передачей запроса вдоль всей цепочки, особенно при наличии большого количества элементов.
  • Сложность отслеживания ошибок, если обработка выполняется несколькими элементами одновременно.

Таким образом, шаблон проектирования Chain of Responsibility полезен тогда, когда вам необходимо создать серию связанных объектов-обработчиков, позволяющих последовательно проверять условия и передавать обработку следующим объектам в цепочке.

Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *