(Head First 设计模式)学习笔记(3) --装饰者模式(StarBuzz咖啡店实例)

来源:互联网 发布:软件项目经理工作流程 编辑:程序博客网 时间:2024/05/01 19:59

以下内容转载请注明来自"菩提树下的杨过(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


被装饰组件之一:“浓咖啡”类

 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


被装饰组件之二:“深培咖啡类”类

 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


装饰者类: “摩卡”调料

 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


最终测试

 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


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