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.

Previous: Adapter · Next: Facade