装饰者模式——(head first 设计模式3)
2013-10-09 23:18
363 查看
装饰者模式定义
装饰者模式动态的将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
从定义来看,除了提到比继承更有弹性,其他的还是非常模糊,下面就先给出其UML类图。
public class Milk : BeverageDecrator { public Milk(Beverage beverage) { this.beverage = beverage; } public override string GetDesciption() { return beverage.description + "-------加牛奶"; } public override double Cost() { SendCoupon(); return beverage.Cost() + 2; } public void SendCoupon() { Console.WriteLine("送优惠券一张"); } }
View Code
输出结果:
![](http://images.cnitblog.com/blog/300932/201310/09231732-30bb85129f7d4d64956d6c00e7b6167b.png)
看看现在修改了牛奶类,没有改变其他地方,就可以得到我们想要的结果了。从而实现了前面所说的原则,开闭原则。
上面设计的问题以及其解决方案
上面的设计好像是遵循了开闭原则,其实则没有,因为类要对扩展开放,对修改关闭,我们很明显,对修改没有关闭,只是对扩展开放而已,现在就来解决修改关闭的问题,要到达这样的效果,就确定了不能改变类的任何地方,只能对类进行扩展,是通过另外一个类,来进行对改类的扩展,这样做的目的是不仅扩展了想要扩展的类,还可以灵活的扩展自己想扩展的类。已达到复用的效果。接下来,看看如何在不改变原有的基础上进行扩展,从而遵循开闭原则。![](http://images.cnitblog.com/blog/300932/201310/10214833-44a01f8248bf43089c7602ff22e16fb4.png)
注意上面的BeverageExtend类,其类多了个SendCoupon方法,(这个方法也是为了显眼而已),用来送优惠券,我们现在修改的是sugar类或Milk类,但是通过的是BeverageExtend类来扩展的,这样才是真正到达了开闭原则。
下面给出扩展类和测试代码
public class BeverageExtend : BeverageDecrator { public BeverageExtend(Beverage beverage) { this.beverage = beverage; } public virtual void SendCoupon() { Console.WriteLine("总价为" + this.Cost()); Console.WriteLine("送您一张优惠券"); } public override string GetDesciption() { return beverage.GetDesciption() + "——————加优惠券"; } public override double Cost() { return beverage.Cost() + 1.5; } }
测试代码:
static void Main(string[] args) { Console.WriteLine("小二哥,来一杯矿泉水加糖"); MineralWater mineralWater = new MineralWater(); Sugar sugar = new Sugar(mineralWater); Console.WriteLine("客官,来了,请慢用"); Console.WriteLine(sugar.GetDesciption()); Console.WriteLine("小二哥,结账"); Console.WriteLine("客官,共"+sugar.Cost()+"¥"); Console.WriteLine("客官慢走"); Console.WriteLine("----------------------------"); Console.WriteLine("小二哥,来一杯矿泉水加糖"); MineralWater mineralWater1 = new MineralWater(); Sugar sugar1 = new Sugar(mineralWater1); BeverageExtend beverage = new BeverageExtend(sugar1); Console.WriteLine("客官,来了,请慢用"); Console.WriteLine(beverage.GetDesciption()); Console.WriteLine("小二哥,结账"); Console.WriteLine("客官,共" + beverage.Cost() + "¥"); Console.WriteLine("客官慢走"); Console.WriteLine("----------------------------"); Console.WriteLine("小二哥,来一杯咖啡加牛奶"); Coffee coffee = new Coffee(); Milk milk = new Milk(coffee); BeverageExtend beverage2 = new BeverageExtend(milk); Console.WriteLine("客官,来了,请慢用"); Console.WriteLine(beverage2.GetDesciption()); Console.WriteLine("小二哥,结账"); Console.WriteLine("客官,共" +beverage2.Cost() + "¥"); Console.WriteLine("客官慢走"); Console.ReadKey(); }
下面给出测试结果图:
![](http://images.cnitblog.com/blog/300932/201310/10214836-033413ced7ab4ba4b60d6b28c8e92606.png)
小结
本文主要通过装饰者模式,引出了设计模式中的开闭原则,通过冷饮店的售价,来体现装饰者如何实现开闭原则的,但是需要注意要对类进行扩展是通过另外一个装饰类来完成的,而不是通过在本身类中实现的。源码:DecratorPattern.zip
相关文章推荐
- 《Head First 设计模式》学习笔记——观察者模式 + 装饰者模式
- [设计模式]head first 设计模式之PHP实现 第三章 装饰者模式
- Head First 设计模式 --3 装饰者模式 开闭原则
- head first 设计模式学习随笔(3)----装饰者模式
- 学习head first 设计模式之装饰者模式
- Head First 设计模式(3):装饰者模式
- (Head First 设计模式)学习笔记(3) --装饰者模式(StarBuzz咖啡店实例)
- 《head first 设计模式》day three 装饰者模式
- Head First 设计模式--装饰者模式
- Head First 设计模式(四)装饰者模式
- (Head First 设计模式)学习笔记(3) --装饰者模式(StarBuzz咖啡店实例)
- Head First 设计模式学习——装饰者模式
- Head First--设计模式(装饰者模式)
- Head First 设计模式 (三) 装饰者模式(decorator pattern) C++实现
- 《Head First 设计模式》阅读笔记(三)——装饰者模式
- Head First 设计模式学习笔记——装饰者模式
- 《Head First 设计模式》学习笔记——装饰者模式
- Head First--设计模式(装饰者模式)
- 《Head First 设计模式》阅读笔记(三)——装饰者模式
- Head First 设计模式(3)- 装饰者模式 笔记