Decorator

Add new functionality to objects dynamically

Overview

The Decorator pattern attaches additional responsibilities to an object dynamically. It provides a flexible alternative to subclassing for extending functionality.

Decorators wrap objects and add behavior before or after delegating to the wrapped object.

Key Concepts

Add responsibilities dynamically

Alternative to subclassing

Decorators wrap the original object

Can stack multiple decorators

Both decorator and decorated implement same interface

Code Example

java
1// Component interface
2interface Coffee {
3    String getDescription();
4    double getCost();
5}
6
7// Concrete component
8class SimpleCoffee implements Coffee {
9    @Override
10    public String getDescription() {
11        return "Simple Coffee";
12    }
13    
14    @Override
15    public double getCost() {
16        return 2.00;
17    }
18}
19
20// Base Decorator
21abstract class CoffeeDecorator implements Coffee {
22    protected Coffee decoratedCoffee;
23    
24    public CoffeeDecorator(Coffee coffee) {
25        this.decoratedCoffee = coffee;
26    }
27    
28    @Override
29    public String getDescription() {
30        return decoratedCoffee.getDescription();
31    }
32    
33    @Override
34    public double getCost() {
35        return decoratedCoffee.getCost();
36    }
37}
38
39// Concrete Decorators
40class MilkDecorator extends CoffeeDecorator {
41    public MilkDecorator(Coffee coffee) {
42        super(coffee);
43    }
44    
45    @Override
46    public String getDescription() {
47        return decoratedCoffee.getDescription() + ", Milk";
48    }
49    
50    @Override
51    public double getCost() {
52        return decoratedCoffee.getCost() + 0.50;
53    }
54}
55
56class SugarDecorator extends CoffeeDecorator {
57    public SugarDecorator(Coffee coffee) {
58        super(coffee);
59    }
60    
61    @Override
62    public String getDescription() {
63        return decoratedCoffee.getDescription() + ", Sugar";
64    }
65    
66    @Override
67    public double getCost() {
68        return decoratedCoffee.getCost() + 0.20;
69    }
70}
71
72class WhipCreamDecorator extends CoffeeDecorator {
73    public WhipCreamDecorator(Coffee coffee) {
74        super(coffee);
75    }
76    
77    @Override
78    public String getDescription() {
79        return decoratedCoffee.getDescription() + ", Whip Cream";
80    }
81    
82    @Override
83    public double getCost() {
84        return decoratedCoffee.getCost() + 0.70;
85    }
86}
87
88// Usage
89public class Main {
90    public static void main(String[] args) {
91        // Plain coffee
92        Coffee coffee = new SimpleCoffee();
93        System.out.println(coffee.getDescription() + " $" + coffee.getCost());
94        
95        // Coffee with milk
96        coffee = new MilkDecorator(coffee);
97        System.out.println(coffee.getDescription() + " $" + coffee.getCost());
98        
99        // Add sugar
100        coffee = new SugarDecorator(coffee);
101        System.out.println(coffee.getDescription() + " $" + coffee.getCost());
102        
103        // Add whip cream
104        coffee = new WhipCreamDecorator(coffee);
105        System.out.println(coffee.getDescription() + " $" + coffee.getCost());
106        // Output: Simple Coffee, Milk, Sugar, Whip Cream $3.40
107    }
108}

Each decorator wraps the coffee and adds its ingredient. They can be stacked in any order.

When to Use

  • Adding responsibilities dynamically

  • When extension by subclassing is impractical

  • Features that can be combined in various ways

  • When you need to add/remove functionality at runtime

Real-World Example

  • Java I/O streams (BufferedInputStream wraps FileInputStream)
  • UI components (adding scrollbars, borders)
  • Text formatting (bold, italic wrappers)
  • Middleware in web frameworks

💡 Interview Tips

  • Show coffee/pizza toppings example

  • Explain stacking decorators

  • Compare with inheritance limitations

  • Mention Java I/O as real example

  • Know difference from Proxy (adds functionality vs controls access)

AI Tutor

Ask about the topic

Sign in Required

Please sign in to use the AI tutor

Sign In
Decorator - Structural Patterns | LLD | Revise Algo