前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >设计模式学习(三): 装饰者模式 (附C#实现)

设计模式学习(三): 装饰者模式 (附C#实现)

作者头像
solenovex
发布2018-03-01 14:35:44
1.1K0
发布2018-03-01 14:35:44
举报
文章被收录于专栏:草根专栏草根专栏

需求

做一个咖啡店的订单系统。

买咖啡时,可以要求加入各种调料,如奶,豆浆,摩卡等。咖啡店会根据调料的不同收取不同的费用。订单系统要考虑这些。

初版设计

然后下面就是所有的咖啡....:

cost方法将计算出咖啡加上各种调料后的价格。

这种方法太笨了。。。必须换一种。

再版设计

使用实例变量和继承!

但是有新的问题:

1.调料价格变化就需要更改现有的代码。

2.一旦出现新的调料,就需要加上新的方法,并改变超类中的cost方法。

3.如果有新的饮料,有些调料可能会不适用。

4.想买双倍的摩卡咖啡怎么办?

设计原则

类应该对扩展开发,对修改关闭。

使用装饰者模式

装饰者模式定义

装饰者模式动态的将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

重新设计

C#代码实现

Beverage:

代码语言:javascript
复制
namespace C03DecoratorPattern.Bases
{
    public abstract class Beverage
    {
        protected string Description;

        protected Beverage()
        {
            Description = "Unknown Beverage";
        }

        public abstract double Cost();

        public virtual string GetDescription()
        {
            return Description;
        }
    }
}

CondimentDecorator:

代码语言:javascript
复制
namespace C03DecoratorPattern.Bases
{
    public abstract class CondimentDecorator : Beverage
    {
        public abstract override double Cost();
        public abstract override string GetDescription();
    }
}

咖啡们:

代码语言:javascript
复制
namespace C03DecoratorPattern.Beverages
{
    public class Espresso : Beverage
    {
        public Espresso()
        {
            Description = "Espresso";
        }

        public override double Cost()
        {
            return 1.99;
        }
    }
}

namespace C03DecoratorPattern.Beverages
{
    public class HouseBlend : Beverage
    {
        public HouseBlend()
        {
            Description = "House Blend Coffee";
        }

        public override double Cost()
        {
            return .89;
        }
    }
}

调料们:

代码语言:javascript
复制
namespace C03DecoratorPattern.Condiments
{
    public class Milk : CondimentDecorator
    {
        private readonly Beverage _beverage;

        public Milk(Beverage beverage)
        {
            _beverage = beverage;
        }

        public override double Cost()
        {
            return .34 + _beverage.Cost();
        }

        public override string GetDescription()
        {
            return $"{_beverage.GetDescription()}, Milk";
        }
    }
}

namespace C03DecoratorPattern.Condiments
{
    public class Mocha : CondimentDecorator
    {
        private readonly Beverage _beverage;

        public Mocha(Beverage beverage)
        {
            _beverage = beverage;
        }
        public override double Cost()
        {
            return .2 + _beverage.Cost();
        }

        public override string GetDescription()
        {
            return $"{_beverage.GetDescription()}, Mocha";
        }
    }
}

namespace C03DecoratorPattern.Condiments
{
    public class Soy: CondimentDecorator
    {
        private readonly Beverage _beverage;

        public Soy(Beverage beverage)
        {
            _beverage = beverage;
        }

        public override double Cost()
        {
            return .17 + _beverage.Cost();
        }

        public override string GetDescription()
        {
            return $"{_beverage.GetDescription()}, Soy";
        }
    }
}

测试程序:

代码语言:javascript
复制
namespace C03DecoratorPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            Beverage beverage = new Espresso();
            Console.WriteLine($"{beverage.GetDescription()} $ {beverage.Cost()}");

            Beverage beverage2 = new HouseBlend();
            beverage2 = new Mocha(beverage2);
            beverage2 = new Milk(beverage2);
            beverage2 = new Soy(beverage2);
            Console.WriteLine($"{beverage2.GetDescription()} $ {beverage2.Cost()}");

            Console.ReadLine();
        }
    }
}

运行结果:

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-10-04 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 需求
  • 初版设计
  • 再版设计
  • 设计原则
  • 使用装饰者模式
  • 装饰者模式定义
  • 重新设计
  • C#代码实现
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档