• (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


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

     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

     

    作者:菩提树下的杨过
    出处:http://yjmyzz.cnblogs.com
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    dpkg安装deb缺少依赖包的解决方法
    一个linux命令之grep---1
    win10快捷键
    Windows Server 2008 R2遗忘管理员密码后的解决方案
    手工释放linux内存
    oracle数据库用户加锁和解锁
    完全卸载Oracle数据库软件
    Linux上VNC 启动和关闭常见问题
    Linux 开启VNCSERVER
    RedHat 简易配置 VNC Server 与VNC View详细说明
  • 原文地址:https://www.cnblogs.com/yjmyzz/p/1205186.html
Copyright © 2020-2023  润新知