Design patterns

Decorator pattern

Classes should be open for extension, but closed for modification

Definition: Attaches additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality

Design principle: Classes should be open for extension but closed for modification

How it works:

Inheritance is a type of extension, but not the best to achieve flexibility. We need designs that allow the behavior to be extended without modifying the existing code. Composition and delegation allow adding new behaviors at runtime. The Decorator Pattern use decorator classes to wrap concrete components. Decorator classes mirror the type of components they decorate through inheritance or interface implementation and change the behavior of their components by adding new functionality before and/or after method calls to the component. A component could be wrapped with any number of decorators. The drawback of this patter is that it can result in many small objects and add complexity to the code.

Let’s look at the code example. Let us compose this type of dessert: vanilla ice-cream with two toppings – jelly beans and caramel syrup.

public abstract class Desert {
    public abstract double cost();
}
public class VanillaIceCream extends Desert {
    public double cost() {
        return 2.50;
    }
}
public abstract class ToppingDecorator extends Desert {
    Desert desert;
}
public class JellyBeans extends ToppingDecorator {
    public JellyBeans (Desert desert) {
        this.desert = desert;
    }
    public double cost() {
        return desert.cost() + 0.30;
    }
}
public class CaramelSyrup extends ToppingDecorator {
    public CaramelSyrup (Desert desert) {
        this.desert = desert;
    }
    public double cost() {
        return desert.cost() + 0.19;
    }
}
public class LittleTreats {
    public static void main (String args[]) {
        Desert rippleIceCream = new VanillaIceCream();
	rippleIceCream = new JellyBeans(rippleIceCream);
	rippleIceCream = new CaramelSyrup(rippleIceCream);
	System.out.println ("Ripple ice-cream cost: " rippleIceCream.cost());
    }
}

Leave a Reply

Your email address will not be published. Required fields are marked *