设计模式学习(三): 装饰者模式 (附C#实现)
2017-10-04 18:27
489 查看
需求
做一个咖啡店的订单系统。买咖啡时,可以要求加入各种调料,如奶,豆浆,摩卡等。咖啡店会根据调料的不同收取不同的费用。订单系统要考虑这些。
初版设计
然后下面就是所有的咖啡....:
cost方法将计算出咖啡加上各种调料后的价格。
这种方法太笨了。。。必须换一种。
再版设计
使用实例变量和继承!但是有新的问题:
1.调料价格变化就需要更改现有的代码。
2.一旦出现新的调料,就需要加上新的方法,并改变超类中的cost方法。
3.如果有新的饮料,有些调料可能会不适用。
4.想买双倍的摩卡咖啡怎么办?
设计原则
类应该对扩展开发,对修改关闭。使用装饰者模式
装饰者模式定义
装饰者模式动态的将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。重新设计
C#代码实现
Beverage:namespace C03DecoratorPattern.Bases { public abstract class Beverage { protected string Description; protected Beverage() { Description = "Unknown Beverage"; } public abstract double Cost(); public virtual string GetDescription() { return Description; } } }
CondimentDecorator:
namespace C03DecoratorPattern.Bases { public abstract class CondimentDecorator : Beverage { public abstract override double Cost(); public abstract override string GetDescription(); } }
咖啡们:
namespace C03DecoratorPattern.Beverages { public class Espresso : Beverage { public Espresso() { Description = "Espresso"; } public override double Cost() { return 1.99; } } } namespace C03DecoratorPattern.Beverages { public class HouseBlend : Beverage { public HouseBlend() { Description = "House Blend Coffee"; } public override double Cost() { return .89; } } }
调料们:
namespace C03DecoratorPattern.Condiments { public class Milk : CondimentDecorator { private readonly Beverage _beverage; public Milk(Beverage beverage) { _beverage = beverage; } public override double Cost() { return .34 + _beverage.Cost(); } public override string GetDescription() { return $"{_beverage.GetDescription()}, Milk"; } } } namespace C03DecoratorPattern.Condiments { public class Mocha : CondimentDecorator { private readonly Beverage _beverage; public Mocha(Beverage beverage) { _beverage = beverage; } public override double Cost() { return .2 + _beverage.Cost(); } public override string GetDescription() { return $"{_beverage.GetDescription()}, Mocha"; } } } namespace C03DecoratorPattern.Condiments { public class Soy: CondimentDecorator { private readonly Beverage _beverage; public Soy(Beverage beverage) { _beverage = beverage; } public override double Cost() { return .17 + _beverage.Cost(); } public override string GetDescription() { return $"{_beverage.GetDescription()}, Soy"; } } }
测试程序:
namespace C03DecoratorPattern { 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); beverage2 = new Milk(beverage2); beverage2 = new Soy(beverage2); Console.WriteLine($"{beverage2.GetDescription()} $ {beverage2.Cost()}"); Console.ReadLine(); } } }
运行结果:
相关文章推荐
- 设计模式学习(四): 1.简单工厂 (附C#实现)
- 《设计模式:基于C#的工程化实现及扩展》学习笔记 02 准备篇 -- Namespace(命名空间)
- 《设计模式:基于C#的工程化实现及扩展》学习笔记--目录
- 设计模式学习——动态代理实现C#动态调用WebService(附源码)
- 《设计模式:基于C#的工程化实现及扩展》学习笔记 01 准备篇 -- 前言
- 深入浅出学习设计模式(C#实现)-组合模式
- C# 设计模式学习四 Builder生成器模式(关于映射实现补充)
- 深入浅出学习设计模式(C#实现)-适配器模式
- 设计模式的学习之路--连接放回连接池装饰者模式实现
- 设计模式-工厂模式(手工作坊到工业化的转变 c#实现)
- C#描述设计模式(2):工厂模式学习心得及我的项目应用
- 从C#的Singleton设计模式实现看.NET Framework特性对开发者的重要性
- C#实现Singleton设计模式
- 设计模式之C#实现(三)FactoryMethod
- 设计模式之C#实现(四)---- ProtoType
- Singleton设计模式的C#实现(下)
- 设计模式之C#实现--FactoryMethod
- singleton设计模式的C#实现(上)
- C#中利用代理实现观察者设计模式
- 设计模式之C#实现---- ProtoType