jobs4timesLogo jobs4timesLogo

Decorator Design Pattern


  • Decorator is one of the widely used structural patterns.
  • It adds dynamically the functionality to an object at runtime without affecting the other objects.
  • It adds additional responsibilities to an object by wrapping it. So it is also called as wrapper.

  • For example, Pizza is the object which is object which is already baked and consider as a base object.
  • As requested by the customer we might need to add some additional toppings on it like cheese or tomato on it, important is only for the object customer requested without effecting other Pizza's.
  • You can consider these toppings as additional responsibilities added by the decorator.

Key Points :
  • Add and remove additional functionalities or responsibilities to an object dynamically at runtime, without affecting the other objects.
  • Usually these decorators are designed on component interface, so you can select the object that has to be decorated at runtime.
  • Sometime adding an additional responsibility to a class may not be possible by sub-classing it. Only available way of achieving it is using decorator.
Following are the participants of the Decorator design pattern :
  1. Component : Pizza is the base interface.
  2. Concrete component : NormalPizza is the concrete implementation of the Pizza interface.
  3. Decorator : is the abstract class who holds the reference of the component and also implements from the component interface.
  4. Concrete Decorator : Who implements from the abstract decorator and add additional responsibilities to the Concrete component.
package design;

public interface Pizza {
   public void bake();	
}
Now implementing the above interface we have a concrete class NormalPizza.
package design;

public class NormalPizza implements Pizza{

	@Override
	public void bake() {
	  System.out.println("Booking normal pizza ...");		
	}
}

Now we want to add some more toppings on the normal pizza. We don't want to modify all the pizza's rather one instance of the normal pizza we want to decorate.

So create Abstract Decoder implementing from Pizza and has reference of Pizza to add toppings.
package design;

public class PizzaDecorator implements Pizza {
	private Pizza pizza;
	
	public PizzaDecorator(Pizza pizza) {
		this.pizza=pizza;
	}

	@Override
	public void bake() {
		pizza.bake();
		
	}
}
Now create an concrete decorator extends from Abstract Decorator to add Tomato as a toppings .
package design;

public class TomatoPizzaDecorator extends PizzaDecorator {

	public TomatoPizzaDecorator(Pizza pizza) {
		super(pizza);
	}
	
	public void bake(){
		super.bake();
		addTomatoTapping();
	}

	public void addTomatoTapping() {
		System.out.println("Tomato topping added ...");		
	}
}
If a PizzaShop wants a TomatoPizza rather modifying the Pizza, he can use TomatoPizzaDecorator as Pizza which decorates the Normal Pizza and serves.
package design;

public class Shop {

public static void main(String[] args){
  Pizza pizza=new TomatoPizzaDecorator(new NormalPizza());
  pizza.bake();
}

}
The UML representation of Decorator Design Pattern :
decorator-design-pattern

BACK