Tutorial List
Home
Interview Questions
Interview
Interview Questions
Links
Web Home
About Us

Decorator Pattern - Make Your Design Flexible

the decorator pattern is a design pattern that allows new/additional behaviour to be added to an existing object dynamically. The decorator pattern is an alternative to subclassing. Inheritance adds behavior at compile time, and the change affects all instances of the original class; decorating can provide new behavior at runtime for individual objects.

Decorator Pattern V/S Inheritance
Inheritance is a powerful feature of OOPS but and it makes design flexible, but it introduces extra lines of codes as you need to create a new subclass for each new behavior. For limited number of subclasses, Inheritance will go well but if functionality increase number of subclass increase as well and it makes design more and more complex.

Lets Take a break and have a coffee:
In coffee menu, we have a base class Coffee. I ask cofeemaker to gimme coffee with milk so he created a subclass MilkCoffee. My friend ask him for coffee with no sugar (Yuk)...so he created another subclass of coffee, so now total we have following classes,
  1. Coffee
  2. CoffeeWithSugar
  3. MilkCoffeeMilk
  4. CoffeeWithSugar
till now, every thing goes fine as coffeemaker create a new subclasss of coffee for each new kind of order, when I went to pay bill, two people came and one asked for coffee with cream and second asked for extra strong coffee.
Now coffee maker has to create following subclass of coffee,
  1. Coffee
  2. CoffeeWithSugar
  3. MilkCoffee
  4. MilkCoffeeWithSugar
  5. CoffeewithCream
  6. CoffeeWithSugerAndCream
  7. MilkcoffeeAndCream
  8. MilkcoffeeWithSugerAndCream
  9. ExtraStongCoffee
  10. ExtraStrongCoffeewithSugar
  11. ExtraStrongMilkCoffee
  12. ExtraStrongMilkCoffeeWithSugar
  13. ExtraStrongCoffeewithCream
  14. ExtraStrongCoffeeWithSugarAndCream
  15. ExtraStrongMilkcoffeeAndCream
  16. ExtraStrongMilkcoffeeWithSugarAndCream
God...he need to handle this number of subclass in his Coffee Application. I was really worried about his application design as when number of demands grow with time, he will end up with Himalaya of subclass as each new request with lead to creation of "N" new subclass where N is number of existing classes. ...

Now,Lets think about Decorator,
For each new request he just need to create one decorator and he can decorate any kind of coffee with that decorator irrespective of number of existing classes,
Like, he can create
Cream Decorator and he can decorate any coffee whether it is Milk Coffee or Extra Strong coffee...
I think we has a lot of theoretical discussion, lets move to example codes as we understand best with simple code snippet,
***********************************************************************
/*Your base coffee class. Here we define only basic coffee making procedure*/
class Coffee
{
public void makeCoffee() {
//secret coffee making procedure
}
}

/*Here we create a base decorator with no custom behavior*/
class CoffeeDecorator extends Coffee
{
protected Coffee objDecoratedCoffee = null;
CoffeeDecorator(Coffee objCoffee) {
this.objDecoratedCoffee = objCoffee;
}
}
/*Here we create Decorator to make Sugared Coffee. This decorator will extends CoffeeDecorator and over-ride the parent class's makeCoffee() method to add sugar to coffee*/
class SugarDecorator extends CoffeeDecorator
{
SugarDecorator(Coffee objCoffee) {
super(objCoffee);
}

public void makeCoffee() {
objDecoratedCoffee.makeCoffee();
addSugar();
// now your sugared coffee is ready
}

protected void addSugar()
{
// add sugar procedure
}
}

/*Here we create Cream Decorator which is similar to SugarDecoarator. The only difference is CreamDecorator over-ride parent class's makeCoffee() method to add cream instead of sugar*/
class CreamDecorator extends CoffeeDecorator
{
CreamDecorator(Coffee objCoffee) {
super(objCoffee);
}

public void makeCoffee() {
objDecoratedCoffee.makeCoffee();
addCream();
}

protected void addCream() {
// add cream procedure
}
}

/*Here is Milk Decorator...*/
class MilkDecorator extends CoffeeDecorator
{
MilkDecorator(Coffee objCoffee) {
super(objCoffee);
}

public void makeCoffee() {
addMilk();
objDecoratedCoffee.makeCoffee();
}

protected void addMilk()
{
// add milk to coffee
}
}

/*This is our Coffee Maker Class which deliver coffee on demand. Please look carefully how we create basic coffee and customize it according to demand*/

public class CoffeeMaker
{
public static void main( String []args) {
// Have Simple Coffee
Coffee objCoffee = new Coffee();
/* Need to add Sugar to Coffee*/
SugarDecorator sugaredCoffee = new SugarDecorator(objCoffee);
sugaredCoffee .makeCoffee();

/* Need to add cream to sugared coffee, just simple.. */
CreamDecorator creamCoffee =
new CreamDecorator(sugaredCoffee );
sugaredExtStrCoffee .majeCoffee();

/*Someone asked for coffee with cream and no sugar*/
CreamDecorator newOrder = new CreamDecorator(new Coffee());
newOrder.makeCoffee();
/*Forgot to add milk, no problem*/
MilkDecorator milkCoffee =
new MilkDecorator(newOrder);
milkCoffee.makeCoffee();
}
}
***********************************************************************
You must have noticed SugerDecorator constructor take Coffee type object hence any Coffee or sub class of coffee can be made with sugar using this single decorator. In other words, SugerDecorator doesn't care whether you are adding sugar to Simple Coffee or Creamed Coffee...it just add the sugar and returns your coffee...and so Cream Decorator does.
That's all, isn't this great. You don't need to make "N" subclasses to get sugared or creamed Coffee of any type but single decorator will do this for you
and your design remains pretty simple and flexible.
In the same way, you can create any type of decorator to add the new behavior irrespective of what kind of coffee your are passing to it, like ExtraHotDecorator...

So lets Summarize it,
Inheritance need 16 subclass to make 5 types of coffee and number of new subclasses increase in Arithmetic progression for any new functionality.
Decorator pattern need 1 base class and 5 Decorator i.e. total 6 classes to have same result and number of classes increase by 1 only for any new functionality
That's all about Decorator pattern. I hope you must have gotten a solid idea about Decorator pattern and how you can use in You Application Design. For any clarification, Please feel free to email me at mohit.amour@gmail.com

Thanks,
The Interpreter

1 comment:

Anonymous said...

Great Tutorial, I really appreciate the content and language...