Autumn SALE
Декоратор

Декоратор на C++

Декоратор — это структурный паттерн, который позволяет добавлять объектам новые поведения на лету, помещая их в объекты-обёртки.

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

Сложность:

Популярность:

Применимость: Паттерн можно часто встретить в C++ коде, особенно в коде, работающем с потоками данных.

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

Концептуальный пример

Этот пример показывает структуру паттерна Декоратор, а именно — из каких классов он состоит, какие роли эти классы выполняют и как они взаимодействуют друг с другом.

main.cc: Пример структуры паттерна

/** * Базовый интерфейс Компонента определяет поведение, которое изменяется * декораторами. */ class Component { public: virtual ~Component() {} virtual std::string Operation() const = 0; }; /** * Конкретные Компоненты предоставляют реализации поведения по умолчанию. Может * быть несколько вариаций этих классов. */ class ConcreteComponent : public Component { public: std::string Operation() const override { return "ConcreteComponent"; } }; /** * Базовый класс Декоратора следует тому же интерфейсу, что и другие компоненты. * Основная цель этого класса - определить интерфейс обёртки для всех конкретных * декораторов. Реализация кода обёртки по умолчанию может включать в себя поле * для хранения завёрнутого компонента и средства его инициализации. */ class Decorator : public Component { /** * @var Component */ protected: Component* component_; public: Decorator(Component* component) : component_(component) { } /** * Декоратор делегирует всю работу обёрнутому компоненту. */ std::string Operation() const override { return this->component_->Operation(); } }; /** * Конкретные Декораторы вызывают обёрнутый объект и изменяют его результат * некоторым образом. */ class ConcreteDecoratorA : public Decorator { /** * Декораторы могут вызывать родительскую реализацию операции, вместо того, * чтобы вызвать обёрнутый объект напрямую. Такой подход упрощает расширение * классов декораторов. */ public: ConcreteDecoratorA(Component* component) : Decorator(component) { } std::string Operation() const override { return "ConcreteDecoratorA(" + Decorator::Operation() + ")"; } }; /** * Декораторы могут выполнять своё поведение до или после вызова обёрнутого * объекта. */ class ConcreteDecoratorB : public Decorator { public: ConcreteDecoratorB(Component* component) : Decorator(component) { } std::string Operation() const override { return "ConcreteDecoratorB(" + Decorator::Operation() + ")"; } }; /** * Клиентский код работает со всеми объектами, используя интерфейс Компонента. * Таким образом, он остаётся независимым от конкретных классов компонентов, с * которыми работает. */ void ClientCode(Component* component) { // ... std::cout << "RESULT: " << component->Operation(); // ... } int main() { /** * Таким образом, клиентский код может поддерживать как простые компоненты... */ Component* simple = new ConcreteComponent; std::cout << "Client: I've got a simple component:\n"; ClientCode(simple); std::cout << "\n\n"; /** * ...так и декорированные. * * Обратите внимание, что декораторы могут обёртывать не только простые * компоненты, но и другие декораторы. */ Component* decorator1 = new ConcreteDecoratorA(simple); Component* decorator2 = new ConcreteDecoratorB(decorator1); std::cout << "Client: Now I've got a decorated component:\n"; ClientCode(decorator2); std::cout << "\n"; delete simple; delete decorator1; delete decorator2; return 0; } 

Output.txt: Результат выполнения

Client: I've got a simple component: RESULT: ConcreteComponent Client: Now I've got a decorated component: RESULT: ConcreteDecoratorB(ConcreteDecoratorA(ConcreteComponent)) 

Декоратор на других языках программирования

Декоратор на C# Декоратор на Go Декоратор на Java Декоратор на PHP Декоратор на Python Декоратор на Ruby Декоратор на Rust Декоратор на Swift Декоратор на TypeScript