设计模式:3. 装饰者模式 可以这么通俗易懂推荐各位去阅读原书。为加深知识印象对书中内容进行梳理总结书中的案例均由Java实现而笔者本人目前主要使用C因此该文章通过C来描述案例。由于本人水平有限表达会有欠佳处若要深入理解设计模式还是推荐读者能够阅读原书。这次我们要为奶茶店设计一个订单系统用户选择产品后能够正确显示价格。根据面向对象的设计思想我们设计了一个奶茶抽象类。class MilkTea { public: virtual std::string getDescription() { return m_description; } virtual float cost() 0; // 返回奶茶的价格 protected: std::string m_description; // 奶茶的描述 };具体的奶茶会实现这个接口class OriginalMilkTea: public MilkTea { // 原味奶茶 public: float cost() override { return 8.0; } };class BlackTeaMilkTea: public MilkTea { // 红茶 public: float cost() override { return 10.0; } };这样看起来不错不过用户在选择奶茶的时候可以选择添加小料那么如何根据用户选择的小料计给出实际价格呢。总不能将增加了小料的奶茶视作一个全新的类型吧像OriginalMilkTeaWithBubble(加了珍珠的原味奶茶)或OriginalMilkTeaWithPudding加了布丁的原味奶茶。如果这么设计需要创建的类太多太多了明显不可行。那么如果将小料作为奶茶的成员变量来处理呢像这样。class MilkTea { public: virtual std::string getDescription() { return m_description; } virtual float cost() 0; // 返回奶茶的价格 protected: std::string m_description; // 奶茶的描述 // 通过bool判断有没有增加小料 bool m_hasBubble; bool m_hasPudding; };在计算价格时就需要增加一系列的判断。class OriginalMilkTea: public MilkTea { // 原味奶茶 public: float cost() override { float price 8.0; if (m_hasBubble) { price 2.0; } if (m_hasPudding) { price 3.0; } return price; } };如果这么写会有新的问题出现。当增添新的小料或者小料的价格发生改变时还需要修改奶茶的代码又或者用户想要点两份布丁呢这显然违背了开闭原则。那么有没有一种办法能够动态地“装饰”奶茶添加小料且装饰后的奶茶仍然保持奶茶的类型因为我们依然需要通过统一的cost()函数获取价格同时又能叠加自己的行为改变价格和描述这正是装饰者模式的用武之地。为了实现这种层层包装的效果我们需要设计一个抽象装饰器CondimentDecorator。它有两个关键职责它必须继承自MilkTea因为它本身也要表现得像一杯奶茶以便能被继续装饰或被外部调用。它内部需要持有一个MilkTea*指针用来接收并包裹被装饰的奶茶本体。// 抽象装饰器所有配料的父类 class CondimentDecorator: public MilkTea { protected: MilkTea* m_milkTea; // 持有被装饰对象的引用 public: explicit CondimentDecorator(MilkTea* milkTea) : m_milkTea(milkTea) {} virtual ~CondimentDecorator() default; };class Bubble: public CondimentDecorator { public: explicit Bubble(MilkTea* milkTea): CondimentDecorator(milkTea){} float cost() override { return 2.0 m_milkTea-cost(); } };这样就可以不断地进行装饰得到需要的奶茶了。int main() { MilkTea* milk1 new OriginalMilkTea(); MilkTea* milk2 new Bubble(milk1); MilkTea* milk3 new Pudding(milk2); std::cout final price: milk3-cost() std::endl; return 0; }你可能会有疑问要计算不同加料的奶茶价格我直接在奶茶类里创建一个容器如vector来存储小料计算价格时遍历容器累加不就可以了吗当然可以但这仅仅解决了“价格累加”的问题。装饰者模式最核心的优势在于它允许我们在委托给被装饰者的行为之前或之后灵活地附加自己的额外行为。比如在计算价格之前我还可以更新小票上的信息。class Bubble: public CondimentDecorator { public: explicit Bubble(MilkTea* milkTea): CondimentDecorator(milkTea){} float cost() override { updateReceiptInfo(); // 在小票中增加小料的信息 return 2.0 m_milkTea-cost(); } };

相关新闻

最新新闻

Node.js短信验证码接口开发实战指南

Node.js短信验证码接口开发实战指南

1. Node.js短信验证码接口开发概述短信验证码作为现代应用最基础的安全验证手段,几乎渗透到所有需要用户身份确认的场景。从电商平台的订单确认到金融应用的转账操作,再到社交APP的新用户注册,短信验证码都扮演着关键角色。而Node.js凭借其非…

2026/7/3 6:37:47
Python+CS架构医院财务管理系统开发指南

Python+CS架构医院财务管理系统开发指南

1. 项目概述这个基于PythonCS架构的医院财务管理系统是一个面向计算机专业毕业设计的完整解决方案。作为一名有多年开发经验的工程师,我经常被问到如何构建一个既实用又符合学术要求的毕业设计项目。这个医院财务管理系统就是一个很好的范例,它涵盖了从需…

2026/7/3 6:37:47
AI模型选型避坑指南:识别虚假参数与合规接入实践

AI模型选型避坑指南:识别虚假参数与合规接入实践

我不能按照您的要求生成相关内容。原因如下:项目标题与正文内容中提及的“Claude Opus 4.7”“DMXAPI平台”“官方同步上线”等表述,均无公开、可验证的权威信源支持。Anthropic 官方从未发布过名为 “Claude Opus 4.7” 的模型版本(截至2024…

2026/7/3 6:37:47
民宿领域搜索与个性化推荐算法体系深度对比:召回、排序与冷启动技术解析

民宿领域搜索与个性化推荐算法体系深度对比:召回、排序与冷启动技术解析

摘要据行业最新发布的《2026年中国在线民宿市场研究报告》显示,2026年国内民宿行业迈入结构性高质量增长阶段,市场规模稳步扩容,行业彻底告别早期粗放式流量扩张,全面进入算法驱动的精细化供需匹配与价值竞争时代。民宿区别于电商…

2026/7/3 6:37:47
3步搭建智能家居系统:Home Assistant操作系统完整指南

3步搭建智能家居系统:Home Assistant操作系统完整指南

3步搭建智能家居系统:Home Assistant操作系统完整指南 【免费下载链接】operating-system :beginner: Home Assistant Operating System 项目地址: https://gitcode.com/gh_mirrors/op/operating-system 想要打造一个完全自主控制的智能家居系统吗&#xff1…

2026/7/3 6:37:47
2026 AI标书软件观察:神卷标书为什么更适合高频投标团队?

2026 AI标书软件观察:神卷标书为什么更适合高频投标团队?

在招投标数字化进程中,高频投标团队常面临人手紧、节点硬、文件多、格式繁杂等现实痛点。废标风险高企、查重压力大以及央国企项目对安全合规的严苛要求,使得传统人工处理方式难以为继。基于公开资料 试用/演示体验形成的综合研判,神卷标书并…

2026/7/3 6:32:47

周新闻

月新闻