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

简介: 以下内容转载请注明来自"菩提树下的杨过(http://blog.sqlsky.com)" 应用概述: StarBuzz咖啡店有很多饮料,每种饮料都可以根据客户需要加一些调料,比如深培咖啡可以加摩卡(或双倍摩卡),而且某些饮料可以分为大中小杯,根据容量不同,售价不同,而且调料的价格根据饮料的容量不同而不同(比如大杯咖啡加糖要1元,中杯咖啡加糖要0.

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

 

目录
相关文章
|
1月前
|
设计模式 缓存 安全
【设计模式】单例模式:确保类只有一个实例
【设计模式】单例模式:确保类只有一个实例
20 0
|
6月前
|
设计模式 安全 Java
JAVA设计模式1:单例模式,确保每个类只能有一个实例
JAVA设计模式1:单例模式,确保每个类只能有一个实例
|
4月前
|
设计模式 Java
Java设计模式【十】:装饰者模式
Java设计模式【十】:装饰者模式
22 0
|
2月前
|
设计模式 缓存 安全
设计模式-代理模式(静态代理、动态代理、cglib代理)、代理模式和装饰者模式的区别
设计模式-代理模式(静态代理、动态代理、cglib代理)、代理模式和装饰者模式的区别
55 1
|
3月前
|
设计模式 Go 开发工具
Golang设计模式——22装饰者模式
Golang设计模式——22装饰者模式
22 0
|
4月前
|
设计模式 Java 数据库
二十三种设计模式全面解析-单例设计模式:解密全局独一无二的实例创造者
二十三种设计模式全面解析-单例设计模式:解密全局独一无二的实例创造者
|
4月前
|
设计模式 Java
根据真实业务场景去实现一下设计模式中的装饰者模式
根据真实业务场景去实现一下设计模式中的装饰者模式
18 0
|
4月前
|
设计模式 人工智能 移动开发
认真学习设计模式之装饰者模式(Decorator Pattern)
写在前言 利用继承设计子类的行为,是在编译时静态决定的,而且所有的子类都会继承到相同的行为。然而如果能够利用组合的做法扩展对象的行为,就可以在运行时动态地进行扩展。通过动态地组合对象,可以写新的代码添加新功能,而无须修改现有代码。既然没有改变现有代码,那么引进bug或产生意外副作用的机会将大幅度减少。
16 0
|
6月前
|
设计模式 Java 应用服务中间件
【设计模式——学习笔记】23种设计模式——职责链/责任链模式(Chain of Responsibility)(原理讲解+应用场景介绍+案例介绍+Java代码实现)
【设计模式——学习笔记】23种设计模式——职责链/责任链模式(Chain of Responsibility)(原理讲解+应用场景介绍+案例介绍+Java代码实现)
76 0
|
6月前
|
设计模式 算法 Java
【设计模式——学习笔记】23种设计模式——策略模式Strategy(原理讲解+应用场景介绍+案例介绍+Java代码实现)
【设计模式——学习笔记】23种设计模式——策略模式Strategy(原理讲解+应用场景介绍+案例介绍+Java代码实现)
57 0