Structural PatternsDecorator PatternMedium⏱️ ~3 min

Decorator Pattern: Structure and Participants

The Decorator Pattern consists of four key participants that work together to enable dynamic behavior composition.

«interface»
Component
+ operation(): void
ConcreteComponent
+ operation(): void
Decorator
- component: Component
+ operation(): void
ConcreteDecoratorA
+ operation(): void
+ addedBehavior(): void
ConcreteDecoratorB
+ operation(): void
+ addedState: Type

Participant Responsibilities:

1. Component (Interface/Abstract Class): Defines the common interface for both concrete components and decorators. This ensures that decorators can be used wherever the original object is expected. All participants must implement operation() to maintain substitutability.

2. ConcreteComponent: The original object to which new responsibilities can be added. It implements the base operation() with core functionality. This is the object being wrapped by decorators. In a coffee shop example, this would be Espresso or DarkRoast.

3. Decorator (Abstract): Maintains a reference to a Component object and implements the Component interface. It forwards requests to the wrapped component by default. Concrete decorators extend this class. This is the key to composition: the decorator HAS-A component (composition) rather than IS-A component (inheritance).

4. ConcreteDecorator: Adds specific responsibilities to the component. It calls the wrapped component's operation() and adds its own behavior before or after. Each concrete decorator can add new methods (addedBehavior()) or state (addedState). Examples include MilkDecorator, WhipDecorator.

Interview Tip: Emphasize that decorators use composition (◆) not inheritance to wrap components. The inheritance from Component is only for type matching, not behavior reuse.

Method Call Flow:

When operation() is called on a decorated object: First, the outermost decorator receives the call. Second, it may perform preprocessing. Third, it delegates to the wrapped component's operation(). Fourth, the wrapped component (which might itself be a decorator) continues the chain. Fifth, the outermost decorator performs postprocessing if needed. Sixth, the result returns up the chain.

💡 Key Takeaways
Component interface defines the contract for both base objects and decorators
ConcreteComponent provides the core functionality being extended
Decorator maintains a reference to Component (composition relationship)
ConcreteDecorators add specific behaviors before/after delegating to wrapped component
Decorators can be stacked: each decorator wraps another component or decorator
📌 Examples
1Component = Beverage, ConcreteComponent = Espresso, Decorators = Milk, Whip
2Component = DataSource, ConcreteComponent = FileDataSource, Decorators = EncryptionDecorator, CompressionDecorator
3Component = Window, ConcreteComponent = SimpleWindow, Decorators = BorderDecorator, ScrollDecorator
← Back to Decorator Pattern Overview
Decorator Pattern: Structure and Participants | Decorator Pattern - System Overflow