Navaneeth K N
Navaneeth K N

Reputation: 15511

Alternatives to decorator pattern

I find decorator pattern to be most confusing. Please consider the example provided in "Head first design patterns book".

alt text

So to get a DarkRoast with double mocha and a whip, you have to write

Beverage beverage2 = new DarkRoast();
beverage2 = new Mocha(beverage2);                                       
beverage2 = new Mocha(beverage2);                                       
beverage2 = new Whip(beverage2); 

I feel this is unnecessary. Here is my implementation,

interface Beverage
{
   int Cost();
}

class DarkRoast : Beverage
{
   /* .... */
}

class Mocha : Beverage
{
   /* .... */
}

class Whip : Beverage
{
   /* .... */
}

// here is the changed part
class Order
{
    List<Beverage> beverages = new List<Beverage> beverages();
    public void AddItem(Beverage b)
    {
        beverages.Add(b);
    }

    public int Cost()
    {
        int cost;
        foreach(Beverage b in beverages)
            cost += b.Cost();
    }
}

// use it like
Order order = new Order();
order.AddItem(new DarkRoast());
order.AddItem(new Mocha());
order.AddItem(new Mocha());
order.AddItem(new Whip());
int cost = order.Cost();

IMO, both does same. If yes, what is the advantage of using decorator pattern here?

Any thoughts?

Upvotes: 6

Views: 5399

Answers (3)

Alberto Gutierrez
Alberto Gutierrez

Reputation: 1588

I think that you are actually representing something completely different.

In your example you have an object call order that receives beverages, and in the Head first example they are just decorating a beverage with toppings, this causes the following main problem.

In your order code, you can place more than one beverage, if so, and you place more than one topping, what topping goes with each beverage?

Upvotes: 1

shahkalpesh
shahkalpesh

Reputation: 33474

No, they are not the same.

Head First example has 1 drink with Mocha, Whip, Roast added. Your example has 3 beverages.
See this Head First code. It works on the same instance of the beverage

beverage2 = new Mocha(beverage2);                                       
beverage2 = new DarkRoast(beverage2);                                       
beverage2 = new Whip(beverage2);

Your code creates 3 beverages (which means someone ordered 3 things separately).
In real life, it is not beverages, I guess. The beverage is one & flavors added on top of it.

The purpose of decorator is - to decorate. .Net has TextWriter and IndentedTextWriter (I guess), which basically takes the normal text of yours and applies indentation to it. It is similar to unix pipes in a way, if you think of it.

input -> tweaks -> tweaked input -> further tweaks -> further tweaked input.
Output of current operation becomes input for next operation.

I don't know if I explained it well.

Upvotes: 15

Karl
Karl

Reputation: 3216

The whole point of the Decorator pattern is to add responsibilities via object composition, not inheritance. Inheritance is static, obj. composition is dynamic and more flexible. The possibilities for decoration are endless. It's also possible to un-decorate an object during runtime.

Upvotes: 10

Related Questions