(Head First 设计模式)学习笔记(3) --装饰者模式(StarBuzz咖啡店实例)
以下内容转载请注明来自"菩提树下的杨过(http://blog.sqlsky.com)"
应用概述:
StarBuzz咖啡店有很多饮料,每种饮料都可以根据客户需要加一些调料,比如深培咖啡可以加摩卡(或双倍摩卡),而且某些饮料可以分为大中小杯,根据容量不同,售价不同,而且调料的价格根据饮料的容量不同而不同(比如大杯咖啡加糖要1元,中杯咖啡加糖要0.9元等)
又一设计原则:
对扩展开放,对修改关闭(本例中各种饮料都有共同的大中小杯特性--这是关闭的部分,另外各种具体子类饮料和调料的描述和价格都不相同--这是开放的部分)
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5
6namespace 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
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5
6namespace 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
被装饰组件之一:“浓咖啡”类
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5
6namespace 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
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5
6namespace 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
被装饰组件之二:“深培咖啡类”类
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5
6namespace 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
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5
6namespace 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
装饰者类: “摩卡”调料
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5
6namespace 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
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5
6namespace 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
最终测试
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5
6namespace 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
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5
6namespace 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
作者:菩提树下的杨过
出处:http://yjmyzz.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
出处:http://yjmyzz.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。