creational

Decorator

Attach additional responsibilities to an object dynamically. A flexible alternative to subclassing.

You want to bolt extra behaviour — logging, encryption, compression, caching, buffering — onto an object, but only onto specific instances and in combinations you can't predict in advance. Solving this with subclasses leads to a combinatorial explosion: EncryptedCompressedBufferedStream, CompressedBufferedStream, and so on for every permutation. Decorator dodges that by layering behaviour at runtime instead of baking it into the type hierarchy.

A plain coffee is your base. Add milk (Decorator 1), add sugar (Decorator 2). Each wraps the previous.

Key Concepts

1
A decorator implements the same interface as the object it wraps and holds a reference to that wrapped object. When called, it does its own work before or after delegating to the wrappee. Because decorators share the component's interface, a decorated object is indistinguishable from a plain one to the client, which means decorators can be stacked: each wraps the previous, forming a chain where a request passes inward through every layer and the response passes back outward. Java's I/O streams are the canonical example — new BufferedReader(new InputStreamReader(...)).
new BufferedReader(new InputStreamReader(...))
2
Use it to add cross-cutting behaviour to individual objects, when subclassing would produce too many combinations, or when you need to add and remove responsibilities at runtime. Two things to watch: order matters — encrypting then compressing is not the same as compressing then encrypting — and a deep stack of tiny decorators can be hard to debug because the call passes through many near-identical layers. Keep each decorator focused on a single added concern.