Time for Decorator pattern:
Use Espresso, DarkRoast and HouseBlend coffee as the ConcreteComponent, Soy, Mocha and Whip as the ConcreteDecorate.
Here is the code:
using System;
namespace DecoratorPattern
{
class Program
{
static void Main(string[] args)
{
Beverage beverage = new Espresso();
Console.WriteLine(beverage.GetDescription() + " $" + beverage.Cost());
Beverage beverage2 = new HouseBlend();
beverage2 = new Mocha(beverage2);
Console.WriteLine(beverage2.GetDescription() + " $" + beverage2.Cost());
Beverage beverage3 = new DarkRoast();
beverage3 = new Whip(beverage3);
beverage3 = new Soy(beverage3);
beverage3 = new Soy(beverage3);
Console.WriteLine(beverage3.GetDescription() + " $" + beverage3.Cost());
Beverage beverage4 = new Espresso();
beverage4 = new Soy(beverage4);
Console.WriteLine(beverage4.GetDescription() + " $" + beverage4.Cost());
}
}
}
namespace DecoratorPattern
{
public abstract class Beverage
{
protected string description = "Unknown beverage";
public virtual string GetDescription()
{
return description;
}
public abstract double Cost();
}
}
namespace DecoratorPattern
{
public abstract class CondimentDecorator : Beverage
{
}
}
namespace DecoratorPattern
{
public class Espresso: Beverage
{
Beverage beverage;
public Espresso()
{
description = "Espresso";
}
public override double Cost()
{
return 2.11;
}
}
}
namespace DecoratorPattern
{
public class DarkRoast:Beverage
{
public DarkRoast()
{
description = "DarkRoast";
}
public override double Cost()
{
return .11;
}
}
}
namespace DecoratorPattern
{
public class HouseBlend:Beverage
{
public HouseBlend()
{
description = "HouseBlend";
}
public override double Cost()
{
return .99;
}
}
}
namespace DecoratorPattern
{
public class Whip:Beverage
{
Beverage beverage;
public Whip(Beverage beverage)
{
this.beverage = beverage;
}
public override string GetDescription()
{
return beverage.GetDescription() + ", Whip";
}
public override double Cost()
{
return beverage.Cost() + .11;
}
}
}
namespace DecoratorPattern
{
public class Soy:Beverage
{
Beverage beverage;
public Soy(Beverage beverage)
{
this.beverage = beverage;
}
public override string GetDescription()
{
return beverage.GetDescription() + ", Soy ";
}
public override double Cost()
{
return beverage.Cost() + .33;
}
}
}
namespace DecoratorPattern
{
public class Mocha:CondimentDecorator
{
Beverage beverage;
public Mocha(Beverage beverage)
{
this.beverage = beverage;
}
public override string GetDescription()
{
return beverage.GetDescription() + ", Mocha ";
}
public override double Cost()
{
return beverage.Cost() + .02;
}
}
}
The diagram from here.
You can find the details of the decription from Head First Design Patterns.