Декоратор (англ. Decorator) — структурный шаблон проектирования, предназначенный для динамического подключения дополнительного поведения к объекту. Шаблон Декоратор предоставляет гибкую альтернативу практике создания подклассов с целью расширения функциональности.
PHP
Пример на PHP
abstract class AbstractComponent { abstract public function operation(); } class ConcreteComponent extends AbstractComponent { public function operation() { // ... } } abstract class AbstractDecorator extends AbstractComponent { protected $component; public function __construct(AbstractComponent $component) { $this->component = $component; } } class ConcreteDecorator extends AbstractDecorator { public function operation() { // ... расширенная функциональность ... $this->component->operation(); // ... расширенная функциональность ... } } $decoratedComponent = new ConcreteDecorator( new ConcreteComponent() ); $decoratedComponent->operation();
Пример на PHP с использованием интерфейсов
interface IText { public function show(); } class TextHello implements IText { protected $object; public function __construct(IText $text) { $this->object = $text; } public function show() { echo 'Hello'; $this->object->show(); } } class TextWorld implements IText { protected $object; public function __construct(IText $text) { $this->object = $text; } public function show() { echo 'world'; $this->object->show(); } } class TextSpace implements IText { protected $object; public function __construct(IText $text) { $this->object = $text; } public function show() { echo ' '; $this->object->show(); } } class TextEmpty implements IText { public function show() { } } $decorator = new TextHello(new TextSpace(new TextWorld(new TextEmpty()))); $decorator->show(); // Hello world echo ' ' . PHP_EOL; $decorator = new TextWorld(new TextSpace(new TextHello(new TextEmpty()))); $decorator->show(); // world Hello
Python
Декораторы в Python предназначены для модификации функций при помощи самих функций. Они используются, когда необходимо изменить поведение функции без изменения кода. Пример.
def decor(func): def wrap(): print("before") func(); print("after"); return wrap deff print_text(): print("Hello world!") deco = decor(print_text) deco()
В данном примере определена функция с именем decor, у которой имеется единственный параметр func. Внутри функции decor определена вложенная фуннкция wrap. Функция wrap выведет строку, затем выполнит функцию, затем выведет еще одну строку. Функция decor возвращает функцию wrap.
В примере дальше определена еще одна функция и переменная. Можно сказать, что переменная deco - это декарированная версия функции print_text.
Python предоставляет удобный способ обернуть любую функую в декоратор; для этого нужно поставить перед определением функции имя декоратора и символ @.
@decor def print_text(): print("Hello world!")