Decorator
Adding behaviour by wrapping, when subclassing every combination would explode.
You want to add behaviour to an object โ buffering to a stream, compression on top of that, encryption on top of that โ and inheritance can't do it, because every *combination* would need its own subclass. Decorator implements the same interface as the thing it wraps, holds a reference to it, and adds its behaviour before or after delegating. Because the wrapper is the same type as the wrapped, they stack arbitrarily and the caller can't tell how deep the pile goes.
The costs show up when something goes wrong. A stack of five decorators produces a stack trace with five nearly identical frames, and finding which layer misbehaved means reading the wiring. Identity gets slippery too โ the decorated object is not the same object, so equality checks, instanceof against concrete types, and anything relying on reference identity can quietly stop working.
The pattern it's confused with is Proxy, and the structures are the same: implement the interface, hold the target, delegate. The difference is intent. A decorator *adds* behaviour and you generally stack several deliberately. A proxy *controls access* to the target โ lazy loading, permission checks, remoting โ and the caller usually isn't meant to know it's there at all.
What they ask, and what to say
Why decorate instead of subclass?
Because combinations explode. Three optional behaviours means seven subclasses to cover every mix, and adding a fourth doubles it. Decorators compose at runtime, so three wrappers cover every combination and the caller picks the stack.
Why they ask: The combinatorial argument is the reason the pattern exists and the cleanest way to show you understand it.
Decorator and Proxy have the same structure. What differs?
Intent. A decorator adds behaviour and is meant to stack. A proxy controls access โ lazy loading, auth, remote calls โ and is usually invisible to the caller. Same shape, different reason for existing.
Why they ask: A favourite follow-up precisely because the diagrams are indistinguishable.
What gets harder once objects are wrapped several layers deep?
Debugging and identity. Stack traces fill with near-identical delegating frames, and the decorated object isn't the same object โ so instanceof against a concrete type, equality, and anything keyed on reference identity can silently break.
Why they ask: Shows operational experience rather than diagram familiarity.