In this article, we will learn how to use and implement the Decorator Pattern in C++ with an example.
Intent
- Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.
- Client-specified embellishment of a core object by recursively wrapping it.
- Wrapping a gift, putting it in a box, and wrapping the box.
C++ Decorator Pattern Example
The below diagram shows the generic structure of the Decorator Pattern:
Let's refer to the above structure to create an example to demonstrates the usage of the Decorator Pattern.
#include <iostream> /* * Component * defines an interface for objects that can have responsibilities * added to them dynamically */ class Component { public: virtual ~Component() {} virtual void operation() = 0; }; /* * Concrete Component * defines an object to which additional responsibilities * can be attached */ class ConcreteComponent : public Component { public: ~ConcreteComponent() {} void operation() { std::cout << "Concrete Component operation" << std::endl; } }; /* * Decorator * maintains a reference to a Component object and defines an interface * that conforms to Component's interface */ class Decorator : public Component { public: ~Decorator() {} Decorator( Component *c ) : component( c ) {} virtual void operation() { component->operation(); } private: Component *component; }; /* * Concrete Decorators * add responsibilities to the component (can extend the state * of the component) */ class ConcreteDecoratorA : public Decorator { public: ConcreteDecoratorA( Component *c ) : Decorator( c ) {} void operation() { Decorator::operation(); std::cout << "Decorator A" << std::endl; } }; class ConcreteDecoratorB : public Decorator { public: ConcreteDecoratorB( Component *c ) : Decorator( c ) {} void operation() { Decorator::operation(); std::cout << "Decorator B" << std::endl; } }; int main() { ConcreteComponent *cc = new ConcreteComponent(); ConcreteDecoratorB *db = new ConcreteDecoratorB( cc ); ConcreteDecoratorA *da = new ConcreteDecoratorA( db ); Component *component = da; component->operation(); delete da; delete db; delete cc; return 0; }
Output
Concrete Component operation
Decorator B
Decorator A
When to Use Decorator Pattern
- Use the Decorator pattern when you need to be able to assign extra behaviors to objects at runtime without breaking the code that uses these objects.
- Use the pattern when it’s awkward or not possible to extend an object’s behavior using inheritance.
Related C++ Design Patterns
- C++ Factory Method Pattern Example
- C++ Builder Pattern Example
- C++ Abstract Factory Pattern Example
- C++ Bridge Pattern Example
- C++ Chain of Responsibility Pattern Example
- C++ Composite Pattern Example
- C++ Decorator Pattern Example
- C++ Facade Pattern Example
- C++ Mediator Pattern Example
- C++ Memento Pattern Example
- C++ Observer Pattern Example
- C++ Proxy Pattern Example
- C++ Strategy Pattern Example
- C++ State Pattern Example
- C++ Visitor Pattern Example
Free Spring Boot Tutorial - 5 Hours Full Course
Watch this course on YouTube at Spring Boot Tutorial | Fee 5 Hours Full Course