Decorator
Intermediate · 16 min read · Low-Level Design, Structural Patterns
Adding behaviour by wrapping, without subclass explosions.
The idea in plain words
You want to add extra behaviour to an object without changing its class. You wrap it in another object that has the same interface, does its extra bit, and passes the call through. Wrappers can be stacked in any order.
The problem: subclass explosion
A notification service sends messages. Requirements grow: some messages need retries, some need rate limiting, some need logging, some need encryption — in any combination.
The solution
Each extra behaviour becomes a wrapper that implements the same interface, holds a reference to another instance of that interface, does its extra work, and delegates the core call.
Order matters
Decorators form a stack; the outermost runs first. Consider what each order means:
Where you've seen it
When to use
Pitfalls
Pros and cons
Comparisons
A memorable line: Decorator changes an object's skin; Strategy changes its guts. Decorator and Composite both use recursive composition, but a decorator has exactly one wrapped component and adds behaviour, while a composite has many children and aggregates their results.
Interview questions
- How is Decorator different from inheritance for adding behaviour?
- Decorator vs Proxy — they look identical. What's the difference?
- You've wrapped a repository with a caching decorator. What can go wrong?
Further reading
Key takeaways
- Decorators implement the same interface as the object they wrap and delegate to it, adding behaviour before or after.
- They replace combinatorial subclassing with composable, runtime wrappers.
- Wrapping order defines behaviour — wire it explicitly in one place.
- Java I/O streams and Collections wrappers are textbook examples.