以下内容转载请注明来自"菩提树下的杨过(http://blog.sqlsky.com)"
应用概述: StarBuzz咖啡店有很多饮料,每种饮料都可以根据客户需要加一些调料,比如深培咖啡可以加摩卡(或双倍摩卡),而且某些饮料可以分为大中小杯,根据容量不同,售价不同,而且调料的价格根据饮料的容量不同而不同(比如大杯咖啡加糖要1元,中杯咖啡加糖要0.9元等)
又一设计原则: 对扩展开放,对修改关闭(本例中各种饮料都有共同的大中小杯特性--这是关闭的部分,另外各种具体子类饮料和调料的描述和价格都不相同--这是开放的部分)
饮料抽象类
1
using
System;
2
using
System.Collections.Generic;
3
using
System.Linq;
4
using
System.Text;
5
6
namespace
StarBazz
7
{ 8 /**/ /// <summary> 9 /// 抽象"饮料"类 10 /// </summary> 11 public abstract class Beverage 12 { 13 protected string description = " Unknown Beverage " ; 14 protected int _Size = ( int )SizeEnum.Big; // 初始化各种饮料均为"大杯" 15 16 public abstract string GetDescription(); // 抽象方法,由"饮料"的具体子类返回各自的描述 17 18 public abstract double GetCost(); // 抽象方法,由"饮料" 19 20 /**/ /// <summary> 21 /// 返回各种饮料的"大中小杯" 22 /// </summary> 23 /// <returns></returns> 24 public int GetSize() 25 { 26 return _Size; 27 }28 29 /**/ /// <summary> 30 /// 设置各种饮料的"大中小杯" 31 /// </summary> 32 /// <param name="size"></param> 33 public void SetSize(SizeEnum size) 34 { 35 _Size = ( int )size; 36 }37 38 39 /**/ /// <summary> 40 /// 大中小杯枚举类型 41 /// </summary> 42 public enum SizeEnum: int 43 { 44 Small = 1 ,Middle = 2 ,Big = 3 45 }46 }47 }
48
49
被装饰组件之一:“浓咖啡”类
1
using
System;
2
using
System.Collections.Generic;
3
using
System.Linq;
4
using
System.Text;
5
6
namespace
StarBazz
7
{ 8 /**/ /// <summary> 9 /// “浓咖啡”类 10 /// </summary> 11 public class Espresso:Beverage 12 { 13 public Espresso() 14 { 15 description = " Espresso " ; // 初始化描述 16 } 17 18 /**/ /// <summary> 19 /// 实现父类的抽象方法GetDescription() 20 /// </summary> 21 /// <returns></returns> 22 public override string GetDescription() 23 { 24 return description; 25 }26 27 /**/ /// <summary> 28 /// 实现父类的抽象方法GetCost() -注:“浓咖啡”不论大中小杯,价格均为1.99元 29 /// </summary> 30 /// <returns></returns> 31 public override double GetCost() 32 { 33 return 1.99 ; 34 }35 }36 }
37
38
被装饰组件之二:“深培咖啡类”类
1
using
System;
2
using
System.Collections.Generic;
3
using
System.Linq;
4
using
System.Text;
5
6
namespace
StarBazz
7
{ 8 /**/ /// <summary> 9 /// “HouseBlend”深培咖啡类 10 /// </summary> 11 public class HouseBlend:Beverage 12 { 13 public HouseBlend() 14 { 15 description = " House Blend Coffee " ; 16 }17 18 /**/ /// <summary> 19 /// 实现父类的抽象方法 20 /// </summary> 21 /// <returns></returns> 22 public override string GetDescription() 23 { 24 return description + " ( " + (Beverage.SizeEnum) this .GetSize() + " ) " ; 25 }26 27 28 /**/ /// <summary> 29 /// 实现父类的抽象方法(大杯0.89元,中杯0.79元,小杯0.68元) 30 /// </summary> 31 /// <returns></returns> 32 public override double GetCost() 33 { 34 double _cost = 0 ; 35 36 switch ( base .GetSize()) 37 { 38 case ( int )Beverage.SizeEnum.Big: 39 _cost = 0.89 ; 40 break ; 41 case ( int )Beverage.SizeEnum.Middle: 42 _cost = 0.79 ; 43 break ; 44 case ( int )Beverage.SizeEnum.Small: 45 _cost = 0.68 ; 46 break ; 47 default : 48 break ; 49 }50 51 return _cost; 52 }53 }54 }
55
56
装饰者类: “摩卡”调料
1
using
System;
2
using
System.Collections.Generic;
3
using
System.Linq;
4
using
System.Text;
5
6
namespace
StarBazz
7
{ 8 /**/ /// <summary> 9 /// “摩卡”调料(用来给其它各种饮料做调味品)--装饰者 10 /// </summary> 11 public class Mocha:Beverage 12 { 13 Beverage _beverage;// 声明一个内部公用的Beverage对象 14 15 /**/ /// <summary> 16 /// 构造函数 17 /// </summary> 18 /// <param name="beverage"></param> 19 public Mocha(Beverage beverage) 20 { 21 _beverage = beverage; 22 description = _beverage.GetDescription(); // 保存被装饰对象的描述 23 _Size = _beverage.GetSize(); // 保存被装饰对象的"大中小杯"值 24 25 }26 27 /**/ /// <summary> 28 /// 实现父类的抽象方法 29 /// </summary> 30 /// <returns></returns> 31 public override string GetDescription() 32 { 33 return description + " ,Mocha " ; 34 }35 36 /**/ /// <summary> 37 /// 实现父类的抽象方法,计算价格(大杯饮料加一份Mocha需要0.2元,中杯饮料加一份Mocha需要0.15元,小杯饮料加一份Mocha需要0.1元) 38 /// </summary> 39 /// <returns></returns> 40 public override double GetCost() 41 { 42 double _cost = this ._beverage.GetCost(); 43 44 switch (_beverage.GetSize()) 45 { 46 case ( int )Beverage.SizeEnum.Big: 47 _cost += 0.2 ; 48 break ; 49 case ( int )Beverage.SizeEnum.Middle: 50 _cost += 0.15 ; 51 break ; 52 case ( int )Beverage.SizeEnum.Small: 53 _cost += 0.1 ; 54 break ; 55 default : 56 break ; 57 }58 59 return _cost; 60 }61 }62 }
63
64
最终测试
1
using
System;
2
using
System.Collections.Generic;
3
using
System.Linq;
4
using
System.Text;
5
6
namespace
StarBazz
7
{ 8 class Program 9 { 10 static void Main( string [] args) 11 { 12 // 先来一份Expresso(浓咖啡),不要任何调料 13 Beverage _beverage = new Espresso(); 14 Console.WriteLine(_beverage.GetDescription() + " Cost: " + _beverage.GetCost().ToString()); // Espresso Cost:1.99 15 16 // 再来一份HouseBlend(深培咖啡) 17 Beverage _beverage2 = new HouseBlend(); 18 Console.WriteLine(_beverage2.GetDescription() + " Cost: " + _beverage2.GetCost().ToString()); // House Blend Coffee(Big) Cost:0.89 19 20 // 客户补充说:只要一份小杯的哦! 21 _beverage2.SetSize(Beverage.SizeEnum.Small); 22 Console.WriteLine(_beverage2.GetDescription() + " Cost: " + _beverage2.GetCost().ToString()); // House Blend Coffee(Small) Cost:0.68 23 24 // 客户要求:我要加二份摩卡 25 Beverage _beverage3 = new Mocha(_beverage2); 26 Console.WriteLine(_beverage3.GetDescription() + " Cost: " + _beverage3.GetCost().ToString()); // House Blend Coffee(Small),Mocha Cost:0.78 27 28 _beverage3 = new Mocha(_beverage3); 29 Console.WriteLine(_beverage3.GetDescription() + " Cost: " + _beverage3.GetCost().ToString()); // House Blend Coffee(Small),Mocha,Mocha Cost:0.88 30 31 Console.ReadLine(); 32 }33 }34 }
35
36
Espresso Cost:1.99 House Blend Coffee(Big) Cost:0.89 House Blend Coffee(Small) Cost:0.68 House Blend Coffee(Small),Mocha Cost:0.78 House Blend Coffee(Small),Mocha,Mocha Cost:0.88