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

Что это такое

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

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


Пример: оборачиваем уведомитель

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

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

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

Prompt
Напишите программу на Go с паттерном Decorator: интерфейс Notifier (метод Send), простой EmailNotifier, декоратор WithLog, который печатает строку лога перед тем, как передать вызов дальше, и декоратор WithSMS, который после вызова ещё отправляет SMS. Оберните email-уведомитель декораторами и отправьте одно сообщение.
Вывод: программа на Go и захваченный вывод
Layers around a core

Когда его использовать

Используйте, чтобы добавить необязательное и комбинируемое поведение — логирование, кеширование, повторные попытки, метрики — вокруг ядра, которое вы не хотите менять. Middleware в веб-серверах — это ровно этот паттерн.

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


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

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

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