Structural Design Pattern · Java

Decorator Design Pattern in Java

Add behavior to an object without changing its original class.

What is Decorator?

Decorator wraps an object that implements the same interface. Multiple decorators can be layered around one component.

Beginner-friendly Java example

The following example shows the central idea of this pattern in a small, practical scenario.

interface Coffee {
    String description();
    double cost();
}

class BasicCoffee implements Coffee {
    public String description() { return "Coffee"; }
    public double cost() { return 3.0; }
}

class MilkDecorator implements Coffee {
    private final Coffee coffee;

    MilkDecorator(Coffee coffee) { this.coffee = coffee; }
    public String description() { return coffee.description() + ", milk"; }
    public double cost() { return coffee.cost() + 0.5; }
}

Benefits and trade-offs

Benefits
  • Separates responsibilities clearly.
  • Improves flexibility as the application grows.
  • Encapsulates structural complexity.
Trade-offs
  • Can introduce extra wrapper classes.
  • Choose the pattern only when the complexity is real.

When should you use it?

  • Adding optional features
  • Building configurable services
  • Java I/O stream wrappers
Key takeawayAdd behavior to an object without changing its original class. Start with the smallest structure that solves the coupling or composition problem.