Decorator Pattern
The Decorator pattern is a structural design pattern that attaches additional responsibilities to an object dynamically by wrapping it in one or more decorator objects that share the same interface as the original.
Definition
The Decorator pattern is a structural design pattern that attaches additional responsibilities to an object dynamically by wrapping it in one or more decorator objects that share the same interface as the original.
Overview
The Decorator pattern, catalogued by the Gang of Four, solves the problem of adding behavior to individual objects without altering the behavior of other instances of the same class and without resorting to a combinatorial explosion of subclasses for every possible combination of features. A decorator implements the same interface as the object it wraps, holds a reference to that wrapped object, and forwards calls to it while adding its own behavior before or after the delegation. Because decorators implement the same interface as the component they wrap, they can be layered — a decorator can wrap another decorator, which wraps another, forming a chain — and the resulting composite object is used interchangeably with an undecorated one anywhere the shared interface is expected. This is distinct from subclassing, which adds behavior statically at compile time to all instances of a class; Decorator adds behavior dynamically, at runtime, to specific object instances, and different instances of the same base class can be wrapped with entirely different combinations of decorators. A canonical textbook example is a text- or stream-processing pipeline: a base `InputStream` might be wrapped by a `BufferedInputStream` decorator, which is wrapped by a `GZIPInputStream` decorator, each adding one capability (buffering, decompression) without the base class needing to know about either. Decorator appears throughout real-world software: Java's I/O library (`java.io`) is a well-known example built almost entirely from layered decorators; Python's function decorators (the `@decorator` syntax) implement a closely related idea at the language level, wrapping functions with additional behavior; web middleware chains (Express.js middleware, ASP.NET middleware, WSGI/ASGI middleware in Python) apply the same wrapping principle to HTTP request handling, where each middleware layer can inspect, modify, or short-circuit the request/response before passing it to the next layer. The tradeoff is that long decorator chains can make debugging and reasoning about the final composed behavior harder, since behavior is spread across many small wrapping layers rather than one place.
Key Concepts
- Wraps an object to add behavior dynamically without modifying its class
- Decorator implements the same interface as the component it wraps
- Decorators can be layered/chained, each adding one discrete responsibility
- Avoids a combinatorial explosion of subclasses for every feature combination
- Adds behavior per-instance at runtime, unlike subclassing which applies statically to all instances
- Underlies stream/I/O libraries, HTTP middleware chains, and language-level function decorators
- Composed objects remain interchangeable with undecorated ones via the shared interface
- Long decorator chains can complicate debugging of the final composed behavior