以下内容转载请注明来自"菩提树下的杨过(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
using System;2
using System.Collections.Generic;3
using System.Linq;4
using System.Text;5

6
namespace StarBazz7
{8
/// <summary>9
/// 抽象"饮料"类10
/// </summary>11
public abstract class Beverage12
{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:int43
{44
Small =1,Middle=2,Big=345
}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
using System;2
using System.Collections.Generic;3
using System.Linq;4
using System.Text;5

6
namespace StarBazz7
{8
/// <summary>9
/// “浓咖啡”类10
/// </summary>11
public class Espresso:Beverage12
{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
using System;2
using System.Collections.Generic;3
using System.Linq;4
using System.Text;5

6
namespace StarBazz7
{8
/// <summary>9
/// “HouseBlend”深培咖啡类10
/// </summary>11
public class HouseBlend:Beverage12
{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
using System;2
using System.Collections.Generic;3
using System.Linq;4
using System.Text;5

6
namespace StarBazz7
{8
/// <summary>9
/// “摩卡”调料(用来给其它各种饮料做调味品)--装饰者10
/// </summary>11
public class Mocha:Beverage12
{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
using System;2
using System.Collections.Generic;3
using System.Linq;4
using System.Text;5

6
namespace StarBazz7
{8
class Program9
{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.9915

16
//再来一份HouseBlend(深培咖啡)17
Beverage _beverage2 = new HouseBlend();18
Console.WriteLine(_beverage2.GetDescription() + " Cost:" + _beverage2.GetCost().ToString());//House Blend Coffee(Big) Cost:0.8919

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.7827

28
_beverage3 = new Mocha(_beverage3);29
Console.WriteLine(_beverage3.GetDescription() + " Cost:" + _beverage3.GetCost().ToString());//House Blend Coffee(Small),Mocha,Mocha Cost:0.8830

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


