views:

593

answers:

3

I was studying Decorator pattern of GOF. It seems to me somehow complecated.

So, please help me understand "Decorator Pattern"? Could you give me an example of this is real world?

+46  A: 

Decorator pattern achieves a single objective of dynamically adding responsibilities to any object.

Consider a case of a pizza shop. In the pizza shop they will sale few pizza varieties and they will also provide toppings in the menu. Now imagine a situation wherein if the pizza shop has to provide prices for each combination of pizza and topping. Even if there are four basic pizzas and 8 different toppings, the application would go crazy maintaining all these concrete combination of pizzas and toppings.

Here comes the decorator pattern.

As per the decorator pattern, you will implement toppings as decorators and pizzas will be decorated by those toppings' decorators. Practically each customer would want toppings of his desire and final bill-amount will be composed of the base pizzas and additionally ordered toppings. Each topping decorator would know about the pizzas that it is decorating and it's price. GetPrice() method of Topping object would return cumulative price of both pizza and the topping.

EDIT

Here's a code-example of explanation above.

public abstract class BasePizza
{
    protected double myPrice;

    public virtual double GetPrice()
    {
        return this.myPrice;
    }
}

public abstract class ToppingsDecorator : BasePizza
{
    protected BasePizza pizza;
    public ToppingsDecorator(BasePizza pizzaToDecorate)
    {
        this.pizza = pizzaToDecorate;
    }

    public override double GetPrice()
    {
        return (this.pizza.GetPrice() + this.myPrice);
    }
}

class Program
{
    [STAThread]
    static void Main()
    {
        //Client-code
        Margherita pizza = new Margherita();
        Console.WriteLine("Plain Margherita: " + pizza.GetPrice().ToString());

        ExtraCheeseTopping moreCheese = new ExtraCheeseTopping(pizza);
        ExtraCheeseTopping someMoreCheese = new ExtraCheeseTopping(moreCheese);
        Console.WriteLine("Plain Margherita with double extra cheese: " + someMoreCheese.GetPrice().ToString());

        MushroomTopping moreMushroom = new MushroomTopping(someMoreCheese);
        Console.WriteLine("Plain Margherita with double extra cheese with mushroom: " + moreMushroom.GetPrice().ToString());

        JalapenoToping moreJalapeno = new JalapenoToping(moreMushroom);
        Console.WriteLine("Plain Margherita with double extra cheese with mushroom with Jalapeno: " + moreJalapeno.GetPrice().ToString());

        Console.ReadLine();
    }
}

public class Margherita : BasePizza
{
    public Margherita()
    {
        this.myPrice = 6.99;
    }
}

public class Gourmet : BasePizza
{
    public Gourmet()
    {
        this.myPrice = 7.49;
    }
}

public class ExtraCheeseTopping : ToppingsDecorator
{
    public ExtraCheeseTopping(BasePizza pizzaToDecorate)
        : base(pizzaToDecorate)
    {
        this.myPrice = 0.99;
    }
}

public class MushroomTopping : ToppingsDecorator
{
    public MushroomTopping(BasePizza pizzaToDecorate)
        : base(pizzaToDecorate)
    {
        this.myPrice = 1.49;
    }
}

public class JalapenoToping : ToppingsDecorator
{
    public JalapenoToping(BasePizza pizzaToDecorate)
        : base(pizzaToDecorate)
    {
        this.myPrice = 1.49;
    }
}

alt text

EDIT2

posted this onto my blog here.

this. __curious_geek
I think a code example in addition might make it clearer
Russ Cam
@Russ: You got it!
this. __curious_geek
+1. What a wonderful and meticulous reply!!!!!
Bragboy
Gotta love those head first patterns. ;-)
Sky Sanders
One of the best replies for details - a diagram also?
andreas
@this.__curious_geek: what a wonderful example ! thank you
odiseh
@this.__curious_geek: (OT) what did you use to create that diagram?
@razass: Class-diagram designer tool of visual-studio-2008. http://www.developingfor.net/visual-studio/visual-studio-2008-class-diagram.html
this. __curious_geek
Thanks andreas, odiseh.
this. __curious_geek
+1  A: 

This is a simple example of adding new behavior to an existing object dynamically, or the Decorator pattern. Due to the nature of dynamic languages such as Javascript, this pattern becomes part of the language itself.

// create a message object
var message = {
    text: "Lorem ipsum dolor sit amet, consectetur adipisicing elit..."
};

// add logging behavior to the message object dynamically
message.log = function() {
    console.log(this.text);
};

// use the newly added behavior to log text
​message.log();​ // Loren ipsum...​​​​​​​​​​​​​​​
Anurag
A: 

It's worth noting that the Java i/o model is based on the decorator pattern. The layering of this reader on top of that reader on top of...is a really real world example of decorator.

frankc