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

简介: 需求 做一个咖啡店的订单系统。 买咖啡时,可以要求加入各种调料,如奶,豆浆,摩卡等。咖啡店会根据调料的不同收取不同的费用。订单系统要考虑这些。 初版设计 然后下面就是所有的咖啡....: cost方法将计算出咖啡加上各种调料后的价格。

需求

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

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

初版设计

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

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

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

再版设计

使用实例变量和继承!

但是有新的问题:

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

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

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

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

设计原则

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

使用装饰者模式

装饰者模式定义

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

重新设计

C#代码实现

Beverage:

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:

namespace C03DecoratorPattern.Bases
{
    public abstract class CondimentDecorator : Beverage
    {
        public abstract override double Cost();
        public abstract override string GetDescription();
    }
}

咖啡们:

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;
        }
    }
}

调料们:

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";
        }
    }
}

测试程序:

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();
        }
    }
}

运行结果:

下面是我的关于ASP.NET Core Web API相关技术的公众号--草根专栏:

目录
相关文章
|
1月前
|
Linux C# 开发者
Uno Platform 驱动的跨平台应用开发:从零开始的全方位资源指南与定制化学习路径规划,助您轻松上手并精通 C# 与 XAML 编程技巧,打造高效多端一致用户体验的移动与桌面应用程序
【9月更文挑战第8天】Uno Platform 的社区资源与学习路径推荐旨在为初学者和开发者提供全面指南,涵盖官方文档、GitHub 仓库及社区支持,助您掌握使用 C# 和 XAML 创建跨平台原生 UI 的技能。从官网入门教程到进阶技巧,再到活跃社区如 Discord,本指南带领您逐步深入了解 Uno Platform,并提供实用示例代码,帮助您在 Windows、iOS、Android、macOS、Linux 和 WebAssembly 等平台上高效开发。建议先熟悉 C# 和 XAML 基础,然后实践官方教程,研究 GitHub 示例项目,并积极参与社区讨论,不断提升技能。
39 2
|
1月前
|
设计模式 C# 开发者
C#设计模式入门实战教程
C#设计模式入门实战教程
|
2月前
|
设计模式 算法 C#
C#设计模式之策略模式
C#设计模式之策略模式
76 19
|
2月前
|
设计模式 安全 程序员
C#设计模式之单例模式
C#设计模式之单例模式
42 3
|
2月前
|
开发框架 .NET API
C#/.NET/.NET Core推荐学习书籍(24年8月更新)
C#/.NET/.NET Core推荐学习书籍(24年8月更新)
|
4月前
|
设计模式 存储 算法
设计模式学习心得之五种创建者模式(2)
设计模式学习心得之五种创建者模式(2)
35 2
|
4月前
|
设计模式 uml
设计模式学习心得之前置知识 UML图看法与六大原则(下)
设计模式学习心得之前置知识 UML图看法与六大原则(下)
29 2
|
3月前
|
Dart 算法 JavaScript
C#数据结构与算法入门教程,值得收藏学习!
C#数据结构与算法入门教程,值得收藏学习!
|
4月前
|
前端开发 Java C#
GitHub突破5k Star!这件事情我坚持了3年,努力打造C#/.NET/.NET Core全面的学习、工作、面试指南知识库
GitHub突破5k Star!这件事情我坚持了3年,努力打造C#/.NET/.NET Core全面的学习、工作、面试指南知识库
|
3月前
|
设计模式 存储 C#