Перейти к основному содержимому

Что это такое

Паттерн Декоратор добавляет объекту поведение, оборачивая его в другой объект с тем же интерфейсом. Каждая обёртка делает свою добавочную часть работы и передаёт вызов дальше — тому, что она оборачивает.

Поскольку обёртка и обёрнутый объект имеют общий интерфейс, обёртки складываются в любых комбинациях — как слои одежды.


Пример: оборачиваем нотификатор

Простой нотификатор отправляет письмо. Одна обёртка добавляет запись в журнал перед отправкой, другая — отправку SMS после неё. Вызывающий код по-прежнему видит обычный Notifier.

Слои вокруг ядра

Запись new WithLog(new WithSMS(new EmailNotifier())) читается изнутри наружу: письмо в ядре, SMS вокруг него, журналирование — самый внешний слой. Любой слой можно добавить, убрать или переставить, не затрагивая остальные.

Prompt
Напишите PHP-скрипт с паттерном «Декоратор»: интерфейс Notifier (метод send), простой EmailNotifier, декоратор WithLog, который печатает строку журнала перед передачей вызова дальше, и декоратор WithSMS, который после этого ещё и отправляет SMS. Оберните декораторами почтовый нотификатор и отправьте одно сообщение.
Вывод: PHP-скрипт
Layers around a core

Когда его применять

Применяйте его, чтобы добавлять необязательное и комбинируемое поведение — журналирование, кеширование, повторные попытки, метрики — вокруг ядра, которое вы не хотите изменять. HTTP-посредники (middleware) в PHP-приложениях оборачивают обработчики запросов именно так.

Откажитесь от него, когда поведение не является необязательным и не комбинируется: тогда его место внутри самого класса, где его легче найти.


Плюсы и минусы

Плюсы: поведение добавляется без изменения основного класса; слои свободно комбинируются; каждый слой мал и тестируется отдельно.

Минусы: глубокий стек обёрток трудно отлаживать — вызов проходит длинный путь, прежде чем что-то сделать; строки создания объектов становятся длинными.