views:

614

answers:

4

I'm a beginner when it comes to design patterns , and I have a question related to the decorator design pattern . Presuming I have a class named A , and I want to use the decorator design pattern . Correct me if I'm wrong , but for that to work , we'll need to create a decorator class ( ADecorator ) , which will hold a reference to an A instance , and all the other decorators will extend this to add functionality .

I don't understand why do we have to create a decorator class , instead of using an A instance ?

+5  A: 

I can't explain it better then the wikipedia article.

Kasper
That almost sounds like a snarky answer, but then I went and looked at the Wikipedia article and yeah, it's excellent. Charade, everything you ever wanted to know is right there, including who, what, when, where and how!
Terry Donaghe
Sorry if it sounded snarky, but english is not my native language, so that kind of "accidents" is bound to happen :-)
Kasper
+1  A: 

In some languages (like Ruby or JavaScript) you could just add new functionality to an A instance. I notice that your question is tagged Java, so I assume that you are asking why you can't do this in Java. The reason is that Java is statically typed. An A instance can only ever have the methods that class A defines or inherits. Therefore, if you want at run time to give an A instance a method that A does not define, then this new method must be defined in a different class.

Glomek
+10  A: 

The decorator pattern is used to add capabilities to objects dynamically (that is, at run time). Normally the object will have its capabilities fixed when you write the class. But an important point is that the functionality of the object is extended in a way that is transparent to the client of the object because it implements the same interface as the original object delegates responsibility to the decorated object.

The decorator pattern works in scenarios where there are many optional functionality that an object may have. Without the decorator pattern you will have to create a different class for each object-option configuration. One example that is pretty useful comes from the Head First Design Patterns book by O'reilly. It uses a coffee shop example that sounds just like StarBucks.

So you have the basic coffee with a method like cost.

public double cost(){
     return 3.45;
}

Then th ecustomer can add cream which cost 0.35 so you now create a CoffeeCream class with the cost method:

public double cost(){
    return 3.80;
}

Then the customer may want Mocha which cost 0.5, and they may want Mocha with Cream or Mocha without Cream. So you create classes CoffeeMochaCream and CoffeeMocha. Then a customer wants double cream so you create a class CoffeeCreamCream...etc etc. What you end up with is class explosion. Please excuse the poor example used. Its a bit late and I know its trivial but it does express the point.

Instead you can create an Item abstarct class with an abstract cost method:

public abstract class Item{
    public abstract double cost();
}

And you can create a concrete Coffee class that extends Item:

public class Coffee extends Item{
    public double cost(){
       return 3.45;
    }
}

Then you create a CoffeeDecorator that extend the same interface and contain an Item.

public abstract class CoffeeDecorator extends Item{
     private Item item;
     ...
}

Then you can create concrete decorators for each option:

public class Mocha extends CoffeeDecorator{

   public double cost(){
     return item.cost() + 0.5;
   }

}

Notice how the decorator does not care what type of object it is wrapping just as long as its an Item? It uses the cost() of the item object and simply adds its own cost.

public class Cream extends CoffeeDecorator{

   public double cost(){
     return item.cost() + 0.35;
   }

}

Now it is possible for a large number of configurations with these few classes: e.g.

 Item drink = new Cream(new Mocha(new Coffee))); //Mocha with cream

or

 Item drink = new Cream(new Mocha(new Cream(new Coffee))));//Mocha with double cream

And so on.

Vincent Ramdhanie
Aha, I guess you're a reader of Head First Design Patterns ?
dhiller
I found this answer easier to comprehend than the Wikipedia article.
Software Monkey
@dhiller Yep. Design Patterns was the first one I tried and have started recommending them to all my students.
Vincent Ramdhanie
This is a example is easier to understand though I don't think this is a right problem that should be solved using this pattern.
noob.spt
+1  A: 

BTW, if you're just starting out on patterns, the Head First Design Patterns book is phenomenal. It really makes the concepts simple to digest, and makes sure to contrast and compare similar patterns in a way that is ridiculously easy to understand.

Spencer K
I have to second this, the book is incredible. In fact the coffee example above is taken from that book but the book takes that example a lot further.
P Arrayah