装饰者模式 Decorator

 项目:咖啡计费系统

背景:现有系统中有一个抽象类Beverage,有2个抽象方法GetDescription和Cost。

复制代码
 1 namespace DecoratorPattern  2 {  3     /// <summary> 4     /// 饮料抽象类  5     /// </summary> 6     public abstract  class Beverage  7     {  8         protected string description = "饮料";  9         protected float price = 0f; 10         public abstract string GetDescription(); 11         12         public abstract float Cost(); 13     } 14 }
复制代码

 

需求:目前有综合咖啡、深焙咖啡、浓缩咖啡,调料有牛奶、摩卡、豆浆、奶泡。未来可能增加新的咖啡种类和调料,当顾客点咖啡时,要求能够获得咖啡的描述和价格。

设计方案1:设计综合咖啡、深焙咖啡、浓缩咖啡4个子类,继承Beverage。再用这4个子类分别派生4个子类,带有牛奶的综合咖啡,带有摩卡的综合咖啡,带有豆浆的综合咖啡...

分析:缺点时显而易见的,这样做导致“类爆炸”,一共需要3*4=12个子类。

设计方案2:把调料作为咖啡的属性设置在Beverage里,并增加方法HasMilk(),SetMilk()等类似的方法。

分析:缺点这样做无疑时从一个灾难跳进另一个灾难中。我们在开发中应当尽量避免修改已有代码,遵循“开闭原则”。而且当增加新的饮料时,又要修改基类。

另一个灾难是,子类在计算价格时,需要大量的分支结构来判断是否包含某种调料,以计算咖啡的价格,我们总是尽量的避免复杂的分支结构,这使得维护变得非常困难。

还有针对实现编程带来的问题,不能够动态的添加职责。

装饰者模式 Decorator 闪亮登场:

装饰者模式动态的将职责附加到对象上。若要扩展共呢个,装饰者提供了比继承更有弹性的替代方案。

1. 4个基类继承Beverage

复制代码
 1 namespace DecoratorPattern  2 {  3     /// <summary> 4     /// 综合咖啡  5     /// </summary> 6     public class HouseBlend:Beverage  7     {  8         public HouseBlend(float price)  9         { 10             this.price = price; 11             this.description = "综合咖啡"; 12         } 13 14         public override float Cost() 15         { 16             return price; 17         } 18         public override string GetDescription() 19         { 20             return this.description; 21         } 22 
                        
关键字:
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信