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 a few pizza varieties and have toppings that customers can order additionally on top of a pizza. Customer can order a pizza and add as many as toppings on the pizza. The cost of the ordered pizza will have to be calculated with pizza and all additional toppings. 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 concrete combination of pizzas and toppings. It is impractical to keep all combination in the menu. You’ll do enough to lose the customer when you expect him to go through such a long menu and do humongous brain-job.
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.
Here’s a code-example of explanation above.
//All your pizzas will inherit from this BasePizza class to identify themselves as pizzas.
public abstract class BasePizza
{
protected double myPrice;
//This method will return the price of the pizza object.
public virtual double GetPrice()
{
return this.myPrice;
}
}
//All toppings will inherit from this ToppingsDecorator class to be able to be added to any pizza in the pizza-shop.
public abstract class ToppingsDecorator : BasePizza
{
//Each topping will need to know to which pizza it is being added to.
protected BasePizza pizza;
public ToppingsDecorator(BasePizza pizzaToDecorate)
{
this.pizza = pizzaToDecorate;
}
//This method will return cumulative price of both pizza and the topping.
public override double GetPrice()
{
return (this.pizza.GetPrice() + this.myPrice);
}
}
class Program
{
[STAThread]
static void Main()
{
//Client-code
//First - order your base pizza. We'll add toppings onto this pizza.
Margherita pizza = new Margherita();
Console.WriteLine("Plain Margherita: " + pizza.GetPrice().ToString());
//Add extra cheese.
ExtraCheeseTopping moreCheese = new ExtraCheeseTopping(pizza);
//Add some more cheese and make it double extra cheese.
ExtraCheeseTopping someMoreCheese = new ExtraCheeseTopping(moreCheese);
Console.WriteLine("Plain Margherita with double extra cheese: " + someMoreCheese.GetPrice().ToString());
//Like mushrroms ? Add that too.
MushroomTopping moreMushroom = new MushroomTopping(someMoreCheese);
Console.WriteLine("Plain Margherita with double extra cheese with mushroom: " + moreMushroom.GetPrice().ToString());
//Throw in some Jalapeno and make it sour and spicy.
JalapenoToping moreJalapeno = new JalapenoToping(moreMushroom);
//Add here's your final pizza.
Console.WriteLine("Plain Margherita with double extra cheese with mushroom with Jalapeno: " + moreJalapeno.GetPrice().ToString());
}
}
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;
}
}
Note that, GetPrice() method of Topping object would return cumulative price of both pizza and the topping.


hi ,
It’s good… awsome as per me no one can bit you in OOAD in ahmedabad….
funny comment : i love pizzas
Comment by pranay rana on July 23, 2010 at 11:59 PM
Thanks for your kind words pranay. But there are many around here whom I learn from and they have real great practical skills of OOAD. I’m striving to keep on learning more and more to improve myself wherever I can and I think that’s the key thing.
Comment by Ruchit on July 24, 2010 at 9:51 AM
Nice article. mouth watering one for both pizza lovers and programmers
Comment by Sujal on July 24, 2010 at 11:52 PM
Very nice explanation about pattern with pizza
Comment by Krunal on July 26, 2010 at 12:14 PM