Wednesday, July 13, 2016

Decorator Design Pattern



This is another design pattern that can be used to decorate an existing object without touching the structure of it. This is very useful design pattern.

Just a moment think about making a coffee. You can make a coffee and then you can add milk or egg as decorators for that existing coffee. It may give additional taste for your coffee. Decorator design pattern gives this approach in simple way.

Decorator design pattern shows how to do that thing in programming. Look at the following diagram to understand.




In this implementation there are few components that are very important to implement Decorator design pattern. I'm going to create a decorator for making a coffee.

  • Basic interface of coffee
  • Basic coffee
  • Coffee decorator
  • Milk coffee
  • Egg coffee
  • Client

Coffee.java

package com.app.design.decorator;

public interface Coffee {
    public String makeCoffee();
} 



BasicCoffee.java

package com.app.design.decorator;

public class BasicCoffee implements Coffee{
    public String makeCoffee(){
        return "Normal coffee";
    }
}



CoffeeDecorator.java

package com.app.design.decorator;

public abstract class CoffeeDecorator implements Coffee {

   protected Coffee coffee;
 
   public CoffeeDecorator(Coffee coffee){
       this.coffee = coffee;
   }
 
   @Override
   public String makeCoffee(){
       return coffee.makeCoffee();
   }
}



MilkCoffee.java

package com.app.design.decorator;

public class MilkCoffee extends CoffeeDecorator {
   public MilkCoffee(Coffee coffee) {
       super(coffee);
   }
 
   public String makeCoffee(){
       return coffee.makeCoffee() + " Milk";
   }
}



EggCoffee.java

package com.app.design.decorator;

public class EggCoffee extends CoffeeDecorator {
    public EggCoffee(Coffee coffee) {
       super(coffee);
    }
 
    public String makeCoffee(){
       return coffee.makeCoffee() + " Egg";
    }
}



Client.java

package com.app.design.decorator;

public class Client {
    public static void main(String[] args){
  
        Coffee coffee = new BasicCoffee();
        System.out.println(coffee.makeCoffee());
  
        Coffee milkCoffee = new MilkCoffee(new BasicCoffee());
        System.out.println(milkCoffee.makeCoffee());
  
        Coffee eggCoffee = new EggCoffee(new BasicCoffee());
        System.out.println(eggCoffee.makeCoffee());
  
        Coffee milkEggCoffee = new EggCoffee(new MilkCoffee(new BasicCoffee()));
        System.out.println(milkEggCoffee.makeCoffee());
    }
}




You may look at both class diagram and these classes. When you run this program, you will be able to see it is very easy to decorate basic coffee with this implementation.

Advantages of Decorator class

  • It is easy to adding new behaviors at run time without compiling the code.
  • Provide flexible approach than inheritance when changing behaviors of objects.

Disadvantages of Decorator class

  • Create many objects
  • Complex to debug code (Because, functions are added in run time)

When it uses in Java ?

  • Decorator is used in Java IO package
    • java.io.BufferedReader
    • java.io.FileReader
    • java.io.Reader