装饰者模式(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是可以一起修饰的,使继承自他的子类可以重写超类的方法。
浙公网安备 33010602011771号