Attach additional responsibilities to an object dynamically, providing a flexible alternative to subclassing for extending functionality. Use it to add responsibilities to individual objects dynamically and transparently without affecting other objects, or when extension by subclassing is impractical due to an explosion of subclasses.
Examples:
- A notification library starts with email-only alerts. Adding SMS, Facebook, and Slack channels as subclasses produces an exponential number of combinations (SMS+Slack, Email+SMS+Facebook, etc.). With Decorator, each channel is a wrapper — an SMSDecorator wraps the base Notifier and adds SMS delivery; stacking decorators at runtime lets you send via every channel simultaneously without new subclasses.
// Decorator wraps a component and forwards requests
class Decorator : public VisualComponent {
public:
Decorator(VisualComponent* component) : _component(component) {}
void Draw() override { _component->Draw(); }
private:
VisualComponent* _component;
};
class BorderDecorator : public Decorator {
public:
BorderDecorator(VisualComponent* c, int w) : Decorator(c), _width(w) {}
void Draw() override { Decorator::Draw(); DrawBorder(_width); }
private:
void DrawBorder(int width);
int _width;
};
Synonyms: wrapper