This is one of the structural design patterns. This pattern acts as a wrapper to the existing class. The Decorator pattern lets us attach additional responsibilities and modify an instance functionality dynamically without affecting the original object or other objects. Decorators provide a flexible alternative to subclassing for extending functionality, using composition instead of inheritance.

Class Diagram

Decorator Pattern in Java

Implementation
Create an Interface

package com.roytuts.designpattern.decorator;
public interface Pizza {
  String size();
  String ingredients();
}

Create an implementation class – VegPizza

package com.roytuts.designpattern.decorator;
public class VegPizza implements Pizza {
  @Override
  public String size() {
    return "Medium";
  }
  @Override
  public String ingredients() {
    return "Vegetables";
  }
}

Create an another implementation class – NonVegPizza

package com.roytuts.designpattern.decorator;
public class NonVegPizza implements Pizza {
  @Override
  public String size() {
    return "Big";
  }
  @Override
  public String ingredients() {
    return "Mutton";
  }
}

Create an abstract class – SubstanceDecorator

package com.roytuts.designpattern.decorator;
public abstract class SubstanceDecorator implements Pizza {
  protected Pizza decoratedPizza;
  public SubstanceDecorator(Pizza decoratedPizza) {
    this.decoratedPizza = decoratedPizza;
  }
  public String size() {
    return decoratedPizza.size();
  }
  public String ingredients() {
    return decoratedPizza.ingredients();
  }
}

Create a concrete class – ChickenDecorator

package com.roytuts.designpattern.decorator;
public class ChickenDecorator extends SubstanceDecorator {
  public ChickenDecorator(Pizza decoratedPizza) {
    super(decoratedPizza);
  }
  @Override
  public String ingredients() {
    return decoratedPizza.ingredients() + " and " + addChicken();
  }
  private String addChicken() {
    return "Add Chicken to Pizza";
  }
}

Create another concrete class – CheeseDecorator

package com.roytuts.designpattern.decorator;
public class CheeseDecorator extends SubstanceDecorator {
  public CheeseDecorator(Pizza decoratedPizza) {
    super(decoratedPizza);
  }
  @Override
  public String ingredients() {
    return decoratedPizza.ingredients() + " and " + addCheese();
  }
  private String addCheese() {
    return "Add Cheese to Pizza";
  }
}

Create a test class for testing the Decorator Pattern

package com.roytuts.designpattern.decorator;
public class DecoratorPatternTest {
  /**
   * @param args
   */
  public static void main(String[] args) {
    Pizza vegPizza = new VegPizza();
    Pizza nonVegPizza = new NonVegPizza();
    SubstanceDecorator cheesePizza = new CheeseDecorator(new VegPizza());
    SubstanceDecorator chickenPizza = new ChickenDecorator(new NonVegPizza());
    System.out.println("Normal Veg Pizza");
    System.out.println("size: " + vegPizza.size());
    System.out.println("ingredients: " + vegPizza.ingredients());
    System.out.println();
    System.out.println("Normal Non Veg Pizza");
    System.out.println("size: " + nonVegPizza.size());
    System.out.println("ingredients: " + nonVegPizza.ingredients());
    System.out.println();
    System.out.println("Veg Pizza after adding Cheese");
    System.out.println("size: " + cheesePizza.size());
    System.out.println("ingredients: " + cheesePizza.ingredients());
    System.out.println();
    System.out.println("Non Veg Pizza after adding Chicken");
    System.out.println("size: " + chickenPizza.size());
    System.out.println("ingredients: " + chickenPizza.ingredients());
    System.out.println();
  }
}

Run the above class. You will see the below output in the console.

Output 

Normal Veg Pizza
size: Medium
ingredients: Vegetables
Normal Non Veg Pizza
size: Big
ingredients: Mutton
Veg Pizza after adding Cheese
size: Medium
ingredients: Vegetables and Add Cheese to Pizza
Non Veg Pizza after adding Chicken
size: Big
ingredients: Mutton and Add Chicken to Pizza

That’s all. Thank you for your reading.

Tags:

Leave a Reply

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