Decorator Design Pattern

What is Decorator Design Pattern?

  • Decorator Design Pattern falls under Structural Design Pattern.
  • We are required to use Decorator Design Pattern whenever our objects need to behave dynamically based on the request.
  • In this pattern, additional responsibilities for an object can be added at the run time without affecting the base object. 

Table of Contents

Real Life Examples of Decorator Design Pattern

Example 1:

ice cream sample photoLet’s suppose; you go to a supermarket to get an ice cream cone. You are asking for a cone ice-cream. Here, the cone is the base object. If a customer asks for vanilla flavor, the vendor will add vanilla flavor in that base object. Adding the demanded flavor, the base object is converted into a customer object based on user request.
This means the base object is added with additional responsibility which is a vanilla flavor in this case. If another customer wants a chocolate flavor, the vendor will add the chocolate flavor ice cream as the additional responsibility at the run time.

Example 2:

pizza sample photoIf we take a plain pizza as an example and a customer orders for chicken pizza, so a chef will add the additional responsibility on the plain pizza which is a chicken layer in this case.
So, when the object should be treated dynamically at the run time based on the criteria, then we should choose Decorator Design Pattern.

UML Class Diagram of Decorator Design Pattern

Decorator Design Pattern Java Implementation

Step 1: Create an interface "Pizza" which would contain an abstract method called "getPizza()"

public interface Pizza
{
    public void getPizza();
}

Step 2: Create a class "Mushroom" pizza which implements "Pizza" interface

public class MushroomPizza implements Pizza
{
    @Override
    public void getPizza()
    {
        System.out.print("Mushroom Pizza");
    }
}

Step 3: Create a class "Chicken" pizza which implements "Pizza" interface

public class ChickenPizza implements Pizza
{
    @Override
    public void getPizza()
    {
        System.out.print("Chicken Pizza");
    }
}

Step 4: Create an abstract class which implements "Pizza" class

public abstract class PizzaDecorator implements Pizza
{
    protected Pizza pizza;
    
    public PizzaDecorator(Pizza pizza)
    {
        this.pizza=pizza;
    }
    
    @Override
    public void getPizza()
    {
        this.pizza.getPizza();
    } 
}

Step 5: Create a Decorator class "PizzaWithToppings" which extends "PizzaDecorator"

public class PizzaWithToppings extends PizzaDecorator
{
    
    public PizzaWithToppings(Pizza pizza)
    {
        super(pizza);
    }
    
    @Override
    public void getPizza()
    {
        pizza.getPizza();
        addToppings();
        
    }
    
    private void addToppings()
    {
        System.out.print(" with toppings");
    }
    
}