The Decorator Pattern

The Decorator Pattern belongs to the groups of the structural design patterns. It is used to modify objects and runtime. You can give instances new behaviour without modifying the class underneath.

In this tutorial we will create a decorator for a pizza service, because everyone loves pizza so what.

 

The Prerequisites

The first thing we do is define a Pizza interface with the method getToppings.

public interface Pizza {
public String getToppings();
}

Now we implement the Interface on a concrete Class called Simple Pizza.

public class SimplePizza implements Pizza {
@Override
public String getToppings() {
return "Pizza normale";
}
}

Straight to the point

Until now we did nothing new. Creating an Interface and implementing it to a concreate class should be nothing new. But things are going to get interesting now.
What if we want a Pizza Funghi, a Pizza Tuna or – god beware – a Pizza Hawaii. We would need to code a class for each one. That means a lot of reduntant code, and as we know: more code means more and harder maintenance.  Maybe a decorator could help us.

public abstract class PizzaDecorator implements Pizza {
protected Pizza pizzaSpeziale;
public PizzaDecorator(Pizza pizzaSpeziale)
{
this.pizzaSpeziale = pizzaSpeziale;
}
public String getToppings(){
return pizzaSpeziale.getToppings();
}
}

The decorator accespts a pizza in its construcor and saves it to a local variable. Here we make use of another very important Design principle ” composition over inheritance”. We dont code against a concrete class but against the Interface. Thus the decorator accepts every class that implements the Pizza interface.

One Pizza with funghis per favore

Okay now that we have implemented an abstract class for our decorator we want get a bit mir concrete. We implement the FunghiDecorator  which extends from PizzaDecorator.  We override the getToppings method by adding some funghis to our Pizza. Thats it. Thats all. It aint that hard is it?

public class FunghiDecorator extends PizzaDecorator {
public FunghiDecorator(Pizza pizzaSpeziale) {
super(pizzaSpeziale);
}
public String getToppings(){
return pizzaSpeziale.getToppings() + addFunghi();
}
private String addFunghi()
{
return " with funghis";
}
}

Here your Pizza funghi sir. Your welcome

To use the decorator we create a simple Pizza which holds the Toppings of a Pizza normale. Unfortunately it has no funghis on top, to change it we invoke the FunghiDecorator upon the simple Pizza object. And because our costumer is very hungry (and greedy) we also invoke a SalamitDecorator upon it (this one is a good exercice for you guys).

public class Main {
public static void main(String[] args) {
Pizza pizza = new SimplePizza();
System.out.println(pizza.getToppings());
pizza = new FunghiDecorator(pizza);
System.out.println(pizza.getToppings());
pizza = new SalamiDecorator(pizza);
System.out.println(pizza.getToppings());
}
}

If we print the toppings of the Pizza we´ll get the following output.

Running the code will produce following output:

Pizza normale
Pizza normale with funghis
Pizza normale with funghis and salami

 

Spread the love