Can you provide a real-world example of the Decorator pattern?

A widely used real-world example of the Decorator pattern is a coffee ordering system, where a base coffee object is wrapped by one or more decorators representing add-ons, each contributing its own cost and description.

Key Points: • A base Coffee interface defines cost() and description(), implemented by a SimpleCoffee class. • Each add-on (milk, sugar, whipped cream) is a decorator class wrapping a Coffee reference. • Every decorator's cost() adds its own price to the wrapped object's cost(), building up the total incrementally. • Decorators can be combined in any order and quantity, e.g. double milk plus sugar, without new subclasses. • This mirrors Java's own I/O classes, where BufferedReader wraps a Reader the same way.

Example: Wrapping new SugarDecorator(new MilkDecorator(new SimpleCoffee())) produces a coffee with milk and sugar added, and calling cost() on the outermost wrapper sums the base price plus both add-ons.

Code Example:

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

class SimpleCoffee implements Coffee {
    public double cost() { return 2.0; }
    public String description() { return "Coffee"; }
}

class MilkDecorator implements Coffee {
    private Coffee coffee;
    MilkDecorator(Coffee coffee) { this.coffee = coffee; }
    public double cost() { return coffee.cost() + 0.5; }
    public String description() { return coffee.description() + " + Milk"; }
}

Interview Tip: A concise interview answer is:

"The go-to real-world example is a coffee shop ordering system: you start with a plain coffee object and wrap it with decorators like milk or sugar, each adding its own cost and description. It avoids needing a separate subclass for every possible combination of add-ons, and it's the same idea Java uses for its I/O stream classes."