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

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

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

饮料抽象类
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

        }

    }

}

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

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;

        }

    }

}

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

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;           

        }

    }

}

装饰者类: “摩卡”调料

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;

        }

    }

}

最终测试

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 条评论
登录 后参与评论

相关文章

来自专栏数据结构与算法

BZOJ2152: 聪聪可可(点分治)

聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃、两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一般情况...

963
来自专栏java一日一条

java提高篇之java的四舍五入

四舍五入是我们小学的数学问题,这个问题对于我们程序猿来说就类似于1到10的加减乘除那么简单了。在讲解之间我们先看如下一个经典的案例:

1332
来自专栏大数据挖掘DT机器学习

使用R语言构造投资组合

原作者: 邓一硕 来自: 格物堂 构造投资组合是金融投资分析中历久弥新的问题。多年以来,学界、业界提出诸多对投资组合进行优化的方法。比如,最经典的基于收益率均...

5506
来自专栏CreateAMind

carla无人驾驶模拟中文项目 carla_simulator_Chinese

2031
来自专栏java学习

Java每日一练(2017/6/3)

Java基础 | 数据库 | Android | 学习视频 | 学习资料下载 课前导读 ●回复"每日一练"获取以前的题目! ●答案公布时间:为每期发布题目的第二...

2826
来自专栏王磊的博客

经典面试题SALES TAXES思路分析和源码分享

题目: SALES TAXES Basic sales tax is applicable at a rate of 10% on all goods, ex...

3056
来自专栏菩提树下的杨过

[你必须知道的.Net]读书笔记--override与new在继承中的区别

前言: 这本书拿到手已经好长时间了,但由于种种原因一直没读完,也许是我太懒了,应该好好反省自我检讨一下。 所谓“书读百遍,其义自见”,虽然糊里糊涂做web开发六...

2149
来自专栏我和未来有约会

[Silverlight动画]转向行为 - 对象回避

对象回避主题的完整意义是指,在机车行走的路线中存在一些障碍物,机车必须绕开、防止触碰到它们。听上去和碰撞检测有关,然而这仅仅是发生在预测阶段,也就是:“以我当前...

2075
来自专栏C语言及其他语言

【每日一题】问题 1146: 舍罕王的失算

关注我们 题目描述 相传国际象棋是古印度舍罕王的宰相达依尔发明的.舍罕王十分喜爱象棋,决定让宰相自己选择何种赏赐.这位聪明的宰相指着8*8共64格的象棋说:陛...

34311
来自专栏数据结构与算法

Day3上午解题报告

预计分数:100+40+50=190 实际分数:100+40+50=190 T1 https://www.luogu.org/problem/show?pid=...

2935

扫码关注云+社区

领取腾讯云代金券