TGViewer
Beer::Code🍺 Beer::Code🍺 @beerphp · 3.64K subscribers
Post #83 5.9K
Decorator pattern

Не подумайте, меня не покусал Егор Бугаенко (для тех кто в теме, кто нет — погуглите), мои взгляды не настолько радикальны, однако я действительно считаю, что этому паттерну уделяют мало внимания. Потому решил познакомить с ним тех, кто не знаком и освежить в памяти для тех, кто уже давно им пользуется.

Декоратор — (wiki) структурный шаблон проектирования, предназначенный для динамического подключения дополнительного поведения к объекту.

👉 Если простым языком, то суть данного паттерна заключается в "оборачивании" существующего объекта новым функционалом, при этом оригинальный интерфейс объекта остается неизменным. В данном примере WrapperObject и есть наш декоратор.

❓ В чем преимущества?

1. Его не получится просто так создать без существования базового класса.
2. Так как базовый класс и класс обертка имплементируют один интерфейс — то они взаимозаменяемы.
3. Мы расширяем поведение без изменения исходного кода.

Стоп, да это же прям Open-Closed Principle! И да, это отличная альтернатива наследованию. Также вы можете использовать несколько разных обёрток одновременно.

❗️ Да, клиентский код выглядит не круто, да и искать все места где вызывается базовый класс, чтобы прицепить обёртку бывает проблематично (особенно в долгоживущих проектах). Однако в фреймворках этот вопрос легко решается. Например в Symfony достаточно добавить всего несколько строк:

Представим, что у нас есть какой-то Mailer, который мы описали в services.yaml и теперь мы хотим логировать отправку всей почты. Для этого у контейнера есть директива decorates. Подобная запись подменит основной mailer на mailer_logger и наши письма начнут начнут логироваться. Для ссылки на исходный класс нужно использовать decorating_service_id + .inner (или просто '@.inner' начиная с Symfony 5.1).

👍 Но что если мы хотим не только логировать, но и отправлять наши письма через очередь? Нет проблем, мы можем добавить еще одну запись. Но как задать порядок в котором будут вызваны декораторы? Для этого существует директива decoration_priority (по умолчанию 0). Соответственно чем выше приоритет — тем раньше применится декоратор (всё логично). Например такой код сначала залогирует (1), а потом уже отправит в очередь (2) наше сообщение:

$this->services['mailer'] = new LoggerDecorator(new QueueDecorator(new Mailler()));

#php #oop #patterns #middle
  • 👍 2
  • ❤ 1
More from @beerphp
  1. Sep 27, 2026Сувора QA Конференція: AI в тестуванні Друзі, буду спікером на онлайн конфі, котра стартує…
  2. Sep 22, 2026Anthropic випустила Opus 5.5 За словами Anthropic, на більшості задач вона працює на рівні…
  3. Sep 21, 2026Доречі, цього тижня буду проводити НОВИЙ воркшоп Harness Engineering - 24 і 26 вересня. Од…
  4. Sep 21, 2026Хочу поділитись своєю мотивацією На тому тижні був воркшоп Agentic Engineering Workflow Ко…
  5. Sep 20, 2026Post #198
  6. Sep 14, 2026Не можу не поділитись, вчора отримав такий відгук Це прям паливо заради якого хочеться про…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →