Design Pattern In Java Part XI Decorator Design Pattern

Posted By : Aftab Alam | 25-Jun-2018

1. Purpose of Design Pattern:- The purpose of design pattern, as per Gang of Four(GoF), to solve recurring problems to design flexible and reusable object-oriented Softwares.

2. Structural Design Pattern:- In Software Engineering, the structural design pattern is those design pattern which makes design easy by identifying a way to realize the relationship between entities.
In other words, structural design pattern deals with structures and relationship among them.

3. The Decorator Design Pattern:- The decorator design pattern falls into the category of the structural design pattern. It allows a behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects of same class.
In other words, it allows adding the behavior to an object dynamically without affecting other objects of same class.

4. Need of Decorator Design Pattern:- In object-oriented programming, inheritance means reusability of code by extending/implementing a class/interface but in some scenario, it is not suitable. That's why there is need of decorator design pattern.

5. The Decorator Design Pattern Implementation:- It implements many classes(s) and interface(s). It's implementation mentioned below.
5.1. It creates one interface which consists of many methods as per need. In this example, interface named as Pizza, it has two methods one for getting the description of a pizza and another for getting cost of a pizza.

public interface Pizza{
   
    String getDescription();
    double getPrice();
}

5.2. A plain pizza class is created which implements pizza interface.

  public class PlainPizza implements Pizza{
  
   public String getDescription(){
      return "Pizza";
   }

   public double getPrice(){
      return 50.00;
   }
}

5.3. A pizza decorator class is created which would be implemented by all kind of pizzas which have any kind of topping accept plain pizza. It overrides both methods and any object of its sub-class is being created passes an object of plain pizza class in its constructor through super keyword.

public class PizzaDecorator implements Pizza{
   
   Pizza pizza;

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

   public String getDescription(){
      return this.pizza.getDescription();
   }

   public double getPrice(){
      return this.pizza.getPrice();
   }
}

5.4. Now, let's focus on implementation class(s) of pizza decorator class.
5.4.1. This class overrides both the methods as per the need of mushroom pizza properties and passes plain pizza class object to its superclass.

public class MushroomPizza extends PizzaDecorator{
  
   public MushroomPizza(Pizza pizza){
      super(pizza);
   }

   public String getDescription(){
     return "Mushroom "+this.pizza.getDescription();
   }

   public double getPrice(){
     return 200+this.pizza.getPrice();
   }
}

5.4.2. This class overrides both the methods as per the need of chicken pizza properties and passes plain pizza class object to its superclass.

public class ChickenPizza extends PizzaDecorator{
  
   public ChickenPizza(Pizza pizza){
      super(pizza);
   }

   public String getDescription(){
     return "Chicken "+this.pizza.getDescription();
   }

   public double getPrice(){
     return 150+this.pizza.getPrice();
   }
}

5.4.3. This class overrides both the methods as per the need of cheese pizza properties and passes plain pizza class object to its superclass.

public class CheesePizza extends PizzaDecorator{
 
   public CheesePizza(Pizza pizza){
     super(pizza);
   }      

   public String getDescription(){
      return "Cheese "+this.pizza.getDescription();
   }

   public double getPrice(){
      return 50+this.pizza.getPrice();
   }
}

5.5. This is the class which demonstrates the demo of decorator design pattern. It does the following things.
i> It displays pizza menu.
ii> It reads user's choice and accordingly creates pizza class object.
iii> By using a created object, it gets description and price of pizza as well as calculates total amount.
iv> If the user is ended with his/her order then it shows total amount to be paid and displays a message that's thanks for visiting this shop.

import java.util.Scanner;

public class DecoratorDesignPattern{
   
   static Scanner scanner=new Scanner(System.in);
   static int choice;
   static double totalAmount=0;

   public static void main(String a[]){
 
      System.out.println("==========Welcome to Pizza Shop==========");
      System.out.println("1. Plain Pizza");
      System.out.println("2. Cheese Pizza");
      System.out.println("3. Chicken Pizza");
      System.out.println("4. Mushroom Pizza");
      System.out.println("5. Exit");
      do{
		choice=scanner.nextInt();
		switch(choice){
			case 1:
				Pizza pizza=new PlainPizza();
				String plainPizzaDescription=pizza.getDescription();
				System.out.println("Description: "+plainPizzaDescription);
				double plainPizzaPrice=pizza.getPrice();
				System.out.println("Price: "+plainPizzaPrice);
                                totalAmount=totalAmount+plainPizzaPrice;
                                System.out.println("Total Amount: "+totalAmount);
				break;
			case 2: 
				CheesePizza cheesePizza=new CheesePizza(new PlainPizza());
			        String cheesePizzaDescription=cheesePizza.getDescription();
			        System.out.println("Description: "+cheesePizzaDescription);
			        double cheesePizzaPrice=cheesePizza.getPrice();
			        System.out.println("Price: "+cheesePizzaPrice);
				totalAmount=totalAmount+cheesePizzaPrice;
                                System.out.println("Total Amount: "+totalAmount);
				break;
			case 3:
				CreamPizza creamPizza=new CreamPizza(new PlainPizza());
			        String creamPizzaDescription=creamPizza.getDescription();
			        System.out.println("Description: "+creamPizzaDescription);
			        double creamPizzaPrice=creamPizza.getPrice();
			        System.out.println("Price: "+creamPizzaPrice);
     				totalAmount=totalAmount+creamPizzaPrice;
                                System.out.println("Total Amount: "+totalAmount);
				break;
			case 4:
				MushroomPizza mushroomPizza=new MushroomPizza(new PlainPizza());
			        String mushroomPizzaDescription=mushroomPizza.getDescription();
			        System.out.println("Description: "+mushroomPizzaDescription);
			        double mushroomPizzaPrice=mushroomPizza.getPrice();
			        System.out.println("Price: "+mushroomPizzaPrice);
     				totalAmount=totalAmount+mushroomPizzaPrice;
                                System.out.println("Total Amount: "+totalAmount);
				break;
			default: 
                                System.out.println("Total Amount to Pay: "+totalAmount);
				System.out.println("Thank You for visiting Pizza Shop.");
				break;
			
		}
      } while(choice!=5);
   }
}

6. Use(s):- It can be used where there is the need for adding behavior to an object dynamically.
6.1. As same as used in pizza example above.
6.2. Browser window.

About Author

Author Image
Aftab Alam

Aftab has worked on multiple technologies in front-end as well as in back-end.

Request for Proposal

Name is required

Comment is required

Sending message..