Java Decorator Pattern: Complete Guide with Pros, Cons & Code Examples
This article provides a comprehensive explanation of the Java Decorator pattern, covering its definition, purpose, advantages, disadvantages, and a complete implementation example with four key roles and runnable code demonstrating dynamic behavior extension.
Java Decorator Pattern
The Java Decorator pattern is a structural design pattern that extends object functionality by wrapping the original object rather than creating subclasses.
Purpose
The primary purpose is to dynamically add extra functionality to an object without changing its interface.
Advantages
Extends object functionality dynamically — adds new behavior without modifying existing code.
Follows Open/Closed Principle — allows extension without modifying existing code.
Follows Single Responsibility Principle — divides functionality across different decorator classes.
Avoids subclass explosion — prevents creating numerous subclasses to extend functionality, improving maintainability and readability.
Disadvantages
Increases complexity — adds code complexity and understanding difficulty; requires careful consideration of class relationships and functional combinations.
Order sensitivity — the calling order of decorator classes can affect the final result and needs special attention.
Runtime overhead — dynamic object creation at runtime may introduce performance overhead.
Implementation Example
The pattern involves four main roles:
1. Component (Abstract Component)
Defines an interface with an abstract operation() method representing the basic operation.
public interface Component { void operation(); }2. ConcreteComponent
Implements the Component interface, providing the basic functionality.
public class ConcreteComponent implements Component { @Override public void operation() { System.out.println("ConcreteComponent.operation()"); } }3. Decorator (Abstract Decorator)
Implements Component interface and holds a reference to a Component object.
public abstract class Decorator implements Component { protected Component component; public Decorator(Component component) { this.component = component; } @Override public void operation() { component.operation(); } }4. ConcreteDecoratorA & ConcreteDecoratorB
Extend Decorator to add specific additional behaviors.
public class ConcreteDecoratorA extends Decorator { public ConcreteDecoratorA(Component component) { super(component); } @Override public void operation() { super.operation(); System.out.println("ConcreteDecoratorA.operation()"); } } public class ConcreteDecoratorB extends Decorator { public ConcreteDecoratorB(Component component) { super(component); } @Override public void operation() { super.operation(); System.out.println("ConcreteDecoratorB.operation()"); } }Usage Demonstration
Decorators can be dynamically applied to add functionality:
Component component = new ConcreteComponent(); component.operation(); component = new ConcreteDecoratorA(component); component.operation(); component = new ConcreteDecoratorB(component); component.operation();Output Result
ConcreteComponent.operation() ConcreteDecoratorA.operation() ConcreteDecoratorB.operation()The output shows the layered execution: first the base component, then each decorator's added behavior in wrapping order.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Architect Chen
Sharing over a decade of architecture experience from Baidu, Alibaba, and Tencent.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
