Decorator Design Pattern

The Decorator Design Pattern is a structural design pattern that allows behavior to be added to individual objects dynamically, without affecting the behavior of other objects from the same class. It involves creating a set of decorator classes that are used to wrap concrete components.

Table of Contents

  1. Characteristics of the Decorator Pattern
  2. Use Cases for the Decorator Pattern
  3. Key Components of the Decorator Design Pattern
  4. Implementation

Characteristics of the Decorator Pattern

Use Cases for the Decorator Pattern

Key Components of the Decorator Design Pattern

Implementation

UML Decorator Pattern

Component Interface(Coffee)

This is the interface Coffee representing the component. It declares two methods getDescription() and getCost() which must be implemented by concrete components and decorators.

// Coffee.java
public interface Coffee {
    String getDescription();
    double getCost();
}

ConcreteComponent(PlainCoffee)

PlainCoffee is a concrete class implementing the Coffee interface. It provides the description and cost of plain coffee by implementing the getDescription() and getCost() methods.

// PlainCoffee.java
public class PlainCoffee implements Coffee {
    @Override
    public String getDescription() {
        return "Plain Coffee";
    }

    @Override
    public double getCost() {
        return 2.0;
    }
}

Decorator(CoffeeDecorator)

CoffeeDecorator is an abstract class implementing the Coffee interface. It maintains a reference to the decorated Coffee object. The getDescription() and getCost() methods are implemented to delegate to the decorated coffee object.

// CoffeeDecorator.java
public abstract class CoffeeDecorator implements Coffee {
    protected Coffee decoratedCoffee;

    public CoffeeDecorator(Coffee decoratedCoffee) {
        this.decoratedCoffee = decoratedCoffee;
    }

    @Override
    public String getDescription() {
        return decoratedCoffee.getDescription();
    }

    @Override
    public double getCost() {
        return decoratedCoffee.getCost();
    }
}

ConcreteDecorators(MilkDecorator,SugarDecorator)

MilkDecorator and SugarDecorator are concrete decorators extending CoffeeDecorator. They override getDescription() to add the respective decorator description to the decorated coffee’s description. They override getCost() to add the cost of the respective decorator to the decorated coffee’s cost.

// MilkDecorator.java
public class MilkDecorator extends CoffeeDecorator {
    public MilkDecorator(Coffee decoratedCoffee) {
        super(decoratedCoffee);
    }

    @Override
    public String getDescription() {
        return decoratedCoffee.getDescription() + ", Milk";
    }

    @Override
    public double getCost() {
        return decoratedCoffee.getCost() + 0.5;
    }
}

// SugarDecorator.java
public class SugarDecorator extends CoffeeDecorator {
    public SugarDecorator(Coffee decoratedCoffee) {
        super(decoratedCoffee);
    }

    @Override
    public String getDescription() {
        return decoratedCoffee.getDescription() + ", Sugar";
    }

    @Override
    public double getCost() {
        return decoratedCoffee.getCost() + 0.2;
    }
}