装饰者模式(headfirst笔记)C#版

装饰者模式(主要是自己的笔记:水平较低,请勿语言攻击)

开放-关闭原则:类应该对扩展开放,对修改关闭

headfirst中的例子,星巴兹咖啡

需求是这样的,几种饮料(价格),可以选择放的调料奶泡(价格)、牛奶(价格)。。。

把客户要加的调料和饮料的价格计算出来。

饮料的超类:Beverage

具体的饮料是:HouseBlend, DarkRoast , Decaf, Espresso

可以加的调料:Milk,Soy,Mocha

第一种尝试,可能有N多的HouseBlendWithMilkAndSoy,HouseBlendWithMilkAndyMocha等待,相当于共有多少种组合在一起

过去的尝试都有数量太多,不合适。

装饰者模式比较适合解决这类问题

装饰者要和被装饰对象有相同的超类型

可以用一个或多个(调料)装饰者包装一个对象(具体的饮料)

装饰者模式可以动态的将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替换方案

publicabstractclass Beverage
{
protectedstring Description ="Unkown Brverage";

publicvirtualstring GetDescription()
{
return Description;
}

publicabstractdouble Cost();
}

publicclass Espresso:Beverage
{
public Espresso()
{
Description
="Espresso";
}

publicoverridedouble Cost()
{
return1.99;
}
}

publicclass HouseBlend : Beverage
{
public HouseBlend()
{
Description
="HouseBlend Coffee";
}

publicoverridedouble Cost()
{
return0.89;
}
}

publicclass DarkRoast : Beverage
{
public DarkRoast()
{
Description
="DarkRoast Coffee";
}

publicoverridedouble Cost()
{
return0.99;
}
}

publicclass Decaf : Beverage
{
public Decaf()
{
Description
="Decaf Coffee";
}

publicoverridedouble Cost()
{
return1.05;
}
}

publicabstractclass CondimentDecorator : Beverage
{
publicabstractoverridestring GetDescription();
}

publicclass Mocha : CondimentDecorator
{
Beverage beverage;

public Mocha(Beverage beverage)
{
this.beverage = beverage;
}

publicoverridestring GetDescription()
{
return beverage.GetDescription() +",Mocha";
}

publicoverridedouble Cost()
{
return .20+ beverage.Cost();
}
}

publicclass Soy : CondimentDecorator
{
Beverage beverage;

public Soy(Beverage beverage)
{
this.beverage = beverage;
}

publicoverridestring GetDescription()
{
return beverage.GetDescription() +",Soy";
}

publicoverridedouble Cost()
{
return .15+ beverage.Cost();
}
}

publicclass Whip : CondimentDecorator
{
Beverage beverage;

public Whip(Beverage beverage)
{
this.beverage = beverage;
}

publicoverridestring GetDescription()
{
return beverage.GetDescription() +",Whip";
}

publicoverridedouble Cost()
{
return .10+ beverage.Cost();
}
}

publicclass Milk : CondimentDecorator
{
Beverage beverage;

public Milk(Beverage beverage)
{
this.beverage = beverage;
}

publicoverridestring GetDescription()
{
return beverage.GetDescription() +",Milk";
}

publicoverridedouble Cost()
{
return .15+ beverage.Cost();
}
}

staticvoid Main(string[] args)
{
//Beverage beverage = new Espresso();
//Console.WriteLine(beverage.GetDescription() + "$" + beverage.Cost());

//Beverage beverage2 = new DarkRoast();
//beverage2 = new Mocha(beverage2);
//beverage2 = new Mocha(beverage2);
//beverage2 = new Whip(beverage2);
//Console.WriteLine(beverage2.GetDescription() + "$" + beverage2.Cost());

//Beverage beverage3 = new HouseBlend();
//beverage3 = new Soy(beverage3);
//beverage3 = new Mocha(beverage3);
//beverage3 = new Whip(beverage3);
//Console.WriteLine(beverage3.GetDescription() + "$" + beverage3.Cost());
}

  其中要注意public abstract override string GetDescription();

abstract和override是可以一起修饰的,使继承自他的子类可以重写超类的方法。

 

posted @ 2011-07-26 13:05  CircleLee  阅读(325)  评论(0)    收藏  举报