Здесь показаны различия между двумя версиями данной страницы.
| Предыдущая версия справа и слева Предыдущая версия | |||
|
php:shablony_proektirovanija:behavioral_patterns:chain_of_responsibilities [2023/08/17 22:51] werwolf |
php:shablony_proektirovanija:behavioral_patterns:chain_of_responsibilities [2023/08/17 22:52] (текущий) werwolf |
||
|---|---|---|---|
| Строка 43: | Строка 43: | ||
| * Цепочка обязанностей и Декоратор имеют очень похожие структуры. Оба паттерна базируются на принципе рекурсивного выполнения операции через серию связанных объектов. Но есть и несколько важных отличий. | * Цепочка обязанностей и Декоратор имеют очень похожие структуры. Оба паттерна базируются на принципе рекурсивного выполнения операции через серию связанных объектов. Но есть и несколько важных отличий. | ||
| * Обработчики в Цепочке обязанностей могут выполнять произвольные действия, независимые друг от друга, а также в любой момент прерывать дальнейшую передачу по цепочке. С другой стороны Декораторы расширяют какое-то определённое действие, не ломая интерфейс базовой операции и не прерывая выполнение остальных декораторов. | * Обработчики в Цепочке обязанностей могут выполнять произвольные действия, независимые друг от друга, а также в любой момент прерывать дальнейшую передачу по цепочке. С другой стороны Декораторы расширяют какое-то определённое действие, не ломая интерфейс базовой операции и не прерывая выполнение остальных декораторов. | ||
| + | |||
| + | |||
| + | **Chain.php** | ||
| + | <code php> | ||
| + | |||
| + | <?php | ||
| + | |||
| + | abstract class Handler | ||
| + | { | ||
| + | private ?Handler $successor; | ||
| + | |||
| + | public function __construct(?Handler $successor) | ||
| + | { | ||
| + | $this->successor = $successor; | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Этот подход с использованием шаблонного метода pattern гарантирует вам, что | ||
| + | * каждый подкласс не забудет вызвать преемника | ||
| + | */ | ||
| + | final public function handle(TaskInterface $task): ?array | ||
| + | { | ||
| + | // запрос не был обработан этим обработчиком => смотрите следующий | ||
| + | $proceed = $this->processing($task); | ||
| + | if ($proceed === null && $this->successor) { | ||
| + | $proceed = $this->successor->handle($task); | ||
| + | } | ||
| + | return $proceed; | ||
| + | } | ||
| + | |||
| + | abstract public function processing(TaskInterface $task): ?array; | ||
| + | } | ||
| + | |||
| + | interface TaskInterface | ||
| + | { | ||
| + | public function getArray(): array; | ||
| + | } | ||
| + | |||
| + | class DevTask implements TaskInterface | ||
| + | { | ||
| + | private array $arr = [1, 2, 3,]; | ||
| + | public function getArray(): array | ||
| + | { | ||
| + | return $this->arr; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | class Senior extends Handler | ||
| + | { | ||
| + | public function processing(TaskInterface $task): ?array | ||
| + | { | ||
| + | return $task->getArray(); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | class Middle extends Handler | ||
| + | { | ||
| + | public function processing(TaskInterface $task): ?array | ||
| + | { | ||
| + | return null; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | class Jun extends Handler | ||
| + | { | ||
| + | public function processing(TaskInterface $task): ?array | ||
| + | { | ||
| + | return null; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | // 1 | ||
| + | $task = new DevTask(); | ||
| + | |||
| + | $senior = new Senior(null); | ||
| + | $middle = new Middle($senior); | ||
| + | $jun = new Jun($middle); | ||
| + | print_r($jun->handle($task)); // вернет массив | ||
| + | |||
| + | // 2 | ||
| + | $task2 = new DevTask(); | ||
| + | |||
| + | $jun = new Jun(null); | ||
| + | print_r($jun->handle($task2)); // НЕ вернет массив | ||
| + | |||
| + | </code> | ||