Decorator Pattern — Adding Behavior Without Subclassing
Fast recall
Quick revision
Core answer
Composition-over-inheritance understanding and ability to design extensible systems
Confusing Decorator with Proxy — both wrap objects, but Decorator adds behavior while Proxy controls access
Reference Java I/O streams as the most famous Decorator example, and Spring Security's filter chain as a real-world application
Interview-ready guide
Interview answer
The Decorator pattern solves a problem inheritance can't handle cleanly: combining behaviors dynamically. If a DataProcessor has four optional behaviors — logging, encryption, compression, validation — inheritance requires 16 subclasses for every combination. Decorator solves this with composition: each behavior is a wrapper class implementing the same interface that delegates to the wrapped object.
The mechanism is straightforward. A decorator holds a reference to another component with the same interface, adds its behavior before or after calling the wrapped method, and returns the result. Callers never know they're dealing with a decorator. You stack them at runtime in any order — the outermost decorator processes first and delegates inward.
Java I/O streams are the most famous example. BufferedInputStream wraps FileInputStream, and GZIPInputStream can wrap either. Each layer adds exactly one responsibility — buffering, compression, decryption — without modifying the others. This is why Java I/O feels composable, even if the explicit constructor chaining is verbose.
The interview distinction that matters is Decorator vs Proxy. Both wrap an object behind the same interface. Decorator adds behavior transparently — the caller doesn't know logging was added. Proxy controls access — caching, lazy loading, transaction management. Spring's @Transactional is a proxy pattern. The security filter chain is closer to a decorator chain. Same structural mechanics, different intent.
Decorator Pattern — Adding Behavior Without Subclassing
Direct Answer
The Decorator pattern wraps an object in another object that implements the same interface, adding behavior before or after delegating to the wrapped object. It avoids a class explosion from subclassing and enables composable behavior at runtime. Java I/O streams (BufferedInputStream wrapping FileInputStream) are the canonical example.
Common Mistakes & Pitfalls
Confusing Decorator with Proxy — both wrap objects, but Decorator adds behavior while Proxy controls access
Check your understanding
Answer these without looking back at the article.
- What is the difference between Decorator and Proxy patterns?
- How does Java I/O use the Decorator pattern?
- When would you prefer Decorator over inheritance?
Related interview prep categories
2Want a guided curriculum order?
These modules are also sequenced in our flagship backend interview track — open it when you prefer an ordered path instead of browsing by topic.