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

2018-01-23 10:02:59 浏览数 (2)

应用概述: StarBuzz咖啡店有很多饮料,每种饮料都可以根据客户需要加一些调料,比如深培咖啡可以加摩卡(或双倍摩卡),而且某些饮料可以分为大中小杯,根据容量不同,售价不同,而且调料的价格根据饮料的容量不同而不同(比如大杯咖啡加糖要1元,中杯咖啡加糖要0.9元等)

又一设计原则: 对扩展开放,对修改关闭(本例中各种饮料都有共同的大中小杯特性--这是关闭的部分,另外各种具体子类饮料和调料的描述和价格都不相同--这是开放的部分)

饮料抽象类
代码语言:javascript复制
using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace StarBazz

{

    /// <summary>

    /// 抽象"饮料"类

    /// </summary>

    public abstract class Beverage

    {

        protected string description = "Unknown Beverage";

        protected int _Size = (int)SizeEnum.Big;//初始化各种饮料均为"大杯"

        public abstract string GetDescription();//抽象方法,由"饮料"的具体子类返回各自的描述

        public abstract double GetCost();//抽象方法,由"饮料"

        /// <summary>

        /// 返回各种饮料的"大中小杯"

        /// </summary>

        /// <returns></returns>

        public int GetSize() 

        {

            return _Size;

        }


        /// <summary>

        /// 设置各种饮料的"大中小杯"

        /// </summary>

        /// <param name="size"></param>

        public void SetSize(SizeEnum size) 

        {

            _Size = (int)size;

        }


        /// <summary>

        /// 大中小杯枚举类型

        /// </summary>

        public enum SizeEnum:int

        {

            Small =1,Middle=2,Big=3

        }

    }

}

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

代码语言:javascript复制
using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace StarBazz

{

    /// <summary>

    /// “浓咖啡”类

    /// </summary>

    public class Espresso:Beverage

    {

        public Espresso() 

        {

            description = "Espresso";//初始化描述

        }



        /// <summary>

        /// 实现父类的抽象方法GetDescription()

        /// </summary>

        /// <returns></returns>

        public override string GetDescription()

        {

            return description;

        }



        /// <summary>

        /// 实现父类的抽象方法GetCost() -注:“浓咖啡”不论大中小杯,价格均为1.99元

        /// </summary>

        /// <returns></returns>

        public override double GetCost() 

        {

            return 1.99;

        }

    }

}

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

代码语言:javascript复制
using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace StarBazz

{

    /// <summary>

    /// “HouseBlend”深培咖啡类

    /// </summary>

    public class HouseBlend:Beverage

    {

        public HouseBlend() 

        {

            description = "House Blend Coffee" ;

        }



        /// <summary>

        /// 实现父类的抽象方法

        /// </summary>

        /// <returns></returns>

        public override string GetDescription()

        {

            return description   "("   (Beverage.SizeEnum)this.GetSize()   ")";

        }


        /// <summary>

        /// 实现父类的抽象方法(大杯0.89元,中杯0.79元,小杯0.68元)

        /// </summary>

        /// <returns></returns>

        public override double GetCost() 

        {

            double _cost = 0;



            switch (base.GetSize())

            {

                case (int)Beverage.SizeEnum.Big:

                    _cost = 0.89;

                    break;

                case (int)Beverage.SizeEnum.Middle:

                    _cost = 0.79;

                    break;

                case (int)Beverage.SizeEnum.Small:

                    _cost = 0.68;

                    break;

                default:

                    break;

            }



            return _cost;           

        }

    }

}

装饰者类: “摩卡”调料

代码语言:javascript复制
using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace StarBazz

{

    /// <summary>

    /// “摩卡”调料(用来给其它各种饮料做调味品)--装饰者

    /// </summary>

    public class Mocha:Beverage

    {

        Beverage _beverage;//声明一个内部公用的Beverage对象

        /// <summary>

        /// 构造函数

        /// </summary>

        /// <param name="beverage"></param>

        public Mocha(Beverage beverage) 

        {

            _beverage = beverage;

            description = _beverage.GetDescription();//保存被装饰对象的描述

            _Size = _beverage.GetSize();//保存被装饰对象的"大中小杯"值

            

        }


        /// <summary>

        /// 实现父类的抽象方法

        /// </summary>

        /// <returns></returns>

        public override string GetDescription() 

        {

            return description   ",Mocha";           

        }



        /// <summary>

        /// 实现父类的抽象方法,计算价格(大杯饮料加一份Mocha需要0.2元,中杯饮料加一份Mocha需要0.15元,小杯饮料加一份Mocha需要0.1元)

        /// </summary>

        /// <returns></returns>

        public override double GetCost()

        {

            double _cost  =  this._beverage.GetCost();



            switch (_beverage.GetSize())

            {

                case (int)Beverage.SizeEnum.Big:

                    _cost  = 0.2;

                    break;

                case (int)Beverage.SizeEnum.Middle:

                    _cost  = 0.15;

                    break;

                case (int)Beverage.SizeEnum.Small:

                    _cost  = 0.1;

                    break;

                default:

                    break;

            }



            return _cost;

        }

    }

}

最终测试

代码语言:javascript复制
using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;



namespace StarBazz

{

    class Program

    {

        static void Main(string[] args)

        {

            //先来一份Expresso(浓咖啡),不要任何调料

            Beverage _beverage = new Espresso();

            Console.WriteLine(_beverage.GetDescription()   " Cost:"   _beverage.GetCost().ToString());//Espresso Cost:1.99



            //再来一份HouseBlend(深培咖啡)

            Beverage _beverage2 = new HouseBlend();

            Console.WriteLine(_beverage2.GetDescription()   " Cost:"   _beverage2.GetCost().ToString());//House Blend Coffee(Big) Cost:0.89



            //客户补充说:只要一份小杯的哦!

            _beverage2.SetSize(Beverage.SizeEnum.Small);            

            Console.WriteLine(_beverage2.GetDescription()   " Cost:"   _beverage2.GetCost().ToString());//House Blend Coffee(Small) Cost:0.68            

            

            //客户要求:我要加二份摩卡

            Beverage _beverage3 = new Mocha(_beverage2);

            Console.WriteLine(_beverage3.GetDescription()   " Cost:"   _beverage3.GetCost().ToString());//House Blend Coffee(Small),Mocha Cost:0.78



            _beverage3 = new Mocha(_beverage3);

            Console.WriteLine(_beverage3.GetDescription()   " Cost:"   _beverage3.GetCost().ToString());//House Blend Coffee(Small),Mocha,Mocha Cost:0.88



            Console.ReadLine();            

        }

    }

}

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

0 人点赞