CodeBlanks Logo Icon CodeBlanks

Decorator

Learn the Decorator pattern.

The Decorator pattern

The Decorator adds behavior by wrapping an object. The wrapping class implements the same interface as the wrapped object, so the client sees no difference. Several decorators can nest.

Example: a Coffee interface, a SimpleCoffee base object. A MilkDecorator takes a Coffee inside and adds the milk price to its cost. new MilkDecorator(new SimpleCoffee()) gives a wrapped coffee. Wrapping is preferred over inheritance, so behavior can be added at runtime.

Nested decorators

Decorators can nest: new SugarDecorator(new MilkDecorator(new SimpleCoffee())). Each layer adds its own contribution; the result is the sum of all layers' costs.

This prevents the inheritance hierarchy from bloating. Instead of a new subclass for each feature, an independent decorator is written. The client customizes the object by picking the layers it wants. This flexibility is common in IO streams (for example BufferedReader).

Practice Add a milk decorator to coffee

Define a Coffee interface with int cost(). A SimpleCoffee class implements it and cost returns 10. A MilkDecorator class implements the Coffee interface; its constructor takes a Coffee inner, and cost returns inner.cost() + 3. In main, wrap with new MilkDecorator(new SimpleCoffee()) and print the cost() result with System.out.println.

Starter code

Main.java
// Define the Coffee interface and SimpleCoffee class
// Wrap with MilkDecorator
// Print the total cost in main

Sample solution

Main.java
interface Coffee { int cost(); }

class SimpleCoffee implements Coffee {
    public int cost() { return 10; }
}

class MilkDecorator implements Coffee {
    private Coffee inner;
    public MilkDecorator(Coffee inner) { this.inner = inner; }
    public int cost() { return inner.cost() + 3; }
}

public class DecoratorDemo {
    public static void main(String[] args) {
        Coffee c = new MilkDecorator(new SimpleCoffee());
        System.out.println(c.cost());
    }
}

Expected output

13

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 What does a Decorator share with the object it wraps?

  • The same interface Correct answer
  • The fields
  • The constructor
  • The static state

Explanation: A Decorator implements the same interface as the wrapped object.

2 Match the Decorator concepts

Term Meaning
Coffee Common interface
SimpleCoffee Base object
MilkDecorator Wrapper
inner.cost() Delegate to inner

3 Complete the Decorator constructor

Question
public MilkDecorator(____ inner) { this.inner = inner; }
Answer
public MilkDecorator(Coffee inner) { this.inner = inner; }

Explanation: The Decorator takes the wrapped type.

All lessons in Advanced