设计模式(三)

设计模式(三)

某些情况,可能会过度地使用继承来扩展对象的功能;

由于继承为类型引入的静态特质,使得这种扩展方式缺乏灵活性;

随着子类增多, 各种子类的组合会导致更多子类的膨胀

需要使用对象功能的扩展,能够根据需要来动态地实现,避免扩展功能的增多带来的子类膨胀

装饰者模式

装饰者模式(Decorator Pattern)是一种结构型设计模式,它允许向一个现有的对象添加新的功能,同时又不改变其结构。这种模式通过创建一个包装对象(装饰者)来包裹真实的对象,并提供增强的功能

eg:咖啡

如果我们想要为咖啡添加不同的调料(如糖、牛奶、巧克力等),我们可能需要为每种可能的组合创建一个类

class Coffee {
public:virtual std::string getDescription() const = 0;virtual double cost() const = 0;
};class SimpleCoffee : public Coffee {
public:std::string getDescription() const override {return "Simple Coffee";}double cost() const override {return 10.0;}
};class CoffeeWithMilk : public Coffee {
public:std::string getDescription() const override {return "Simple Coffee with Milk";}double cost() const override {return 12.0; // Coffee cost + Milk cost}
};class CoffeeWithSugar : public Coffee {
public:std::string getDescription() const override {return "Simple Coffee with Sugar";}double cost() const override {return 11.0; // Coffee cost + Sugar cost}
};// ... 更多组合类 ...

这种无脑的使用继承,会造成子类过于繁多,臃肿;

解决方法是:

通过组合来增加灵活性,继承是编译时静态决定的;而组合则是运行时,动态地添加或更换组件

​ 继承会导致子类和父类紧密的耦合,父类若变,子类有可能都受影响

​ 组合可以重用 不同类的对象和功能

使用装饰者模式:

创建一个装饰者基类,然后为每种调料创建一个装饰者类

class Coffee {
public:virtual std::string getDescription() const = 0;virtual double cost() const = 0;virtual ~Coffee() {}
};class SimpleCoffee : public Coffee {
public:std::string getDescription() const override {return "Simple Coffee";}double cost() const override {return 10.0;}
};// Decorator
class CoffeeDecorator : public Coffee {
protected:Coffee* coffee;public:CoffeeDecorator(Coffee* coffee) : coffee(coffee) {}std::string getDescription() const override {return coffee->getDescription();}double cost() const override {return coffee->cost();}
};// Concrete Decorators
class Milk : public CoffeeDecorator {
public:Milk(Coffee* coffee) : CoffeeDecorator(coffee) {}std::string getDescription() const override {return CoffeeDecorator::getDescription() + ", Milk";}double cost() const override {return CoffeeDecorator::cost() + 2.0; // Milk cost}
};class Sugar : public CoffeeDecorator {
public:Sugar(Coffee* coffee) : CoffeeDecorator(coffee) {}std::string getDescription() const override {return CoffeeDecorator::getDescription() + ", Sugar";}double cost() const override {return CoffeeDecorator::cost() + 1.0; // Sugar cost}
};// ... 更多装饰者类 ...

这样就可以动态的添加调料到咖啡中

int main() {Coffee* myCoffee = new SimpleCoffee();std::cout << myCoffee->getDescription() << " - $" << myCoffee->cost() << std::endl;myCoffee = new Milk(myCoffee);std::cout << myCoffee->getDescription() << " - $" << myCoffee->cost() << std::endl;myCoffee = new Sugar(myCoffee);std::cout << myCoffee->getDescription() << " - $" << myCoffee->cost() << std::endl;// Clean updelete myCoffee;return 0;
}/*输出:Simple Coffee - $10Simple Coffee, Milk - $12Simple Coffee, Milk, Sugar - $13
*/

可以看到,在装饰者类中

既继承了父类,又定义了父类;即:is-a has-a

同时继承父类,组合子类

通常这种继承父类,又再类中定义了父类,八成是装饰者模式

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/883588.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

openssl 自签证书

生成自签证书脚本 #!/bin/bash KEY_LENGTH4096 DAYS3650 STDongBei LLiaoNing ONASA OUNASA CN*.dongbei.nasa.edu.cn EMAILxxxqq.com# 生成私有证书密钥 openssl genrsa -out server.key ${KEY_LENGTH} # 生成证书请求文件 # 警告:一定要用双引号&#xff08;单引号不解析变量…

信创认证(信创人才考评证书)的含金量?到底有多少?

“信创认证”是什么&#xff1f; 信创认证是由工业和信息化部教育与考试中心推出的国家级权威认证&#xff0c;旨在推动信息技术应用创新产业的发展&#xff0c;并构建完善的信创产业人才培养体系。该认证在个人信息技术领域具有极高的认可度。 信创认证分为初级、中级和高级三…

新手铲屎官提问,有哪几款噪音低的宠物空气净化器推荐

相信很多铲屎官都明白的的痛就是猫咪掉毛太严重&#xff0c;所以每次看到满天飞的浮毛时只想赶紧逃离&#xff0c;一点都不想清理。但是家是自己的&#xff0c;猫是自己的&#xff0c;健康也是自己的&#xff0c;不清理也得清理。 为了更有效的清理浮毛&#xff0c;我朋友特意…

参会记录|2024 中国计算机大会(CNCC 2024)

前言&#xff1a;2024年10月24-26日&#xff0c;有幸在横店参加了2024年度的中国计算机大会&#xff08;CNCC&#xff09;&#xff0c;本篇博客总结本人在会议期间收听的主要报告内容及收获。 2024.10.24 上午 夏苑海岳开襟 如何实现人工智能在现实场景中的落地&#xff1f; …

OgCloud参加HPE Discover More AI 2024,共建数智化未来!

10月16日&#xff0c;企业科技盛会HPE Discover More AI 2024在香港瑰丽酒店举行。本次大会Hewlett Packard Enterprise (HPE) 联同全球14个科技合作伙伴&#xff0c;聚焦于AI未来走势、混合云创新与边缘安全等领域&#xff0c;以主题演讲、技术展示、研讨会等形式进行&#xf…

从双斜率,野人除法看性能优化

人呐&#xff0c;天生对线性的推崇&#xff0c;却在内心又对线性的不爱。一开始人们总是从最简单的线性过程入手&#xff0c;但最终都难免因为不满足而进入指数过程。 看一个 Linux kernel 老式 O(1) 调度器的时间片计算函数的演化&#xff1a; 早期的 O(1) 是一个连续线性函…

vue 解决:npm ERR! code ERESOLVE 及 npm ERR! ERESOLVE could not resolve 的方案

1、问题描述&#xff1a; 其一、需求为&#xff1a; 想要安装项目所需依赖&#xff0c;成功运行 vue 项目&#xff0c;想要在浏览器中能成功访问项目地址 其二、问题描述为&#xff1a; 在 package.json 文件打开终端平台&#xff0c;通过执行 npm install 命令&#xff0c…

【MySQL】视图特性 用户管理

> 作者&#xff1a;დ旧言~ > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;了解什么是视图&#xff0c;我们又该如何管理用户。 > 毒鸡汤&#xff1a;有些事情&#xff0c;总是不明白&#xff0c;所以我不会坚持。早安! >…

kafka 如何减少数据丢失?

大家好&#xff0c;我是锋哥。今天分享关于【kafka 如何减少数据丢失?】面试题&#xff1f;希望对大家有帮助&#xff1b; kafka 如何减少数据丢失? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Apache Kafka 是一个高吞吐量的分布式消息队列&#xff0c;广泛用…

简单记录ios打包流程

1、点击这里获取UDID 2、xcode登录开发者账户、确定唯一id&#xff08;Bundle ID&#xff09; 3、去这里注册appid 4、在这里这里创建app 5、之后xcode中打包

Mac 出现zsh: command not found: aapt

Mac 运行aapt命令 提示&#xff1a;zsh: command not found: aapt 这个问题是Mac本地没有配置 aapt的 环境变量。理论上本地有Android Studio&#xff0c;aapt是默认配置了的&#xff0c;无奈要用到aapt&#xff0c;还是配置下吧。 mac zsh 配置 aapt 环境变量的方法&#xf…

前端对一个增删改查的思考

1、来源&#xff1a;dify dify/web/app/components/workflow/nodes/question-classifier/components/class-list.tsx at main langgenius/dify GitHub 2、代码流程&#xff1a; 3、思索问题&#xff1a; 1、为啥要用return形式&#xff0c;而不是value直接当函数&#xff1…

SQL进阶技巧:如何求组内排除当前行的移动平均值?

目录 0 需求描述 2 数据准备 3 问题分析 4 小结 0 需求描述 -- 按照 日期,省份,等级 分组 求分数的平均值;但是需要剔除当前行的数据 2 数据准备 create table avgtest as (select 2024-10-24 as cdate, 广东 as province,深圳 as city, 2 as level, 200 as scoreunio…

ssm005基于SSM框架的购物商城系统的开发与实现(论文+源码)_kaic

设计题目&#xff1a;购物商城系统的设计与实现 摘 要 网络技术和计算机技术发展至今&#xff0c;已经拥有了深厚的理论基础&#xff0c;并在现实中进行了充分运用&#xff0c;尤其是基于计算机运行的软件更是受到各界的关注。加上现在人们已经步入信息时代&#xff0c;所以对…

【MyBatis】| JavaWeb基础教程学习笔记(上)

01-MyBatis简介 什么是MyBatis? MyBatis是一款优秀的持久层框架&#xff0c;用于简化JDBC开发MyBatis本是Apache的一个开源项目iBatis&#xff0c;2010年这个项目由apache software foundation迁移到了google code&#xff0c;并且改名为MyBatis。2013年11月迁移到Github官网…

双11必买物品清单有哪些?双11推荐购买清单推荐分享

随着一年一度的“双十一”购物狂欢节的到来&#xff0c;各大电商平台纷纷推出了各种优惠活动和促销策略&#xff0c;让消费者在享受购物乐趣的同时也能获得实实在在的优惠。然而&#xff0c;面对琳琅满目的商品和纷繁复杂的促销活动&#xff0c;双11必买物品清单有哪些成为了一…

面向对象进阶(下)(JAVA笔记第二十五期)

p.s.这是萌新自己自学总结的笔记&#xff0c;如果想学习得更透彻的话还是请去看大佬的讲解 目录 抽象方法和抽象类抽象方法定义格式抽象类定义格式抽象方法和抽象类注意事项 接口接口的定义接口中成员变量的特点接口中没有构造方法接口中成员方法的特点在接口中定义具有方法体…

vue3中ref和reactive的用法,区别和优缺点,以及使用场景

写在前头&#xff1a; reactive定义的数据只能修改里面的属性&#xff0c;不能将整个数据替换&#xff0c;实在要替换请使用 Object.assign(obj1, obj2);举个例子 这种写法无法直接改变obj1 let obj1 reactive({name: 猫,age: 2, });obj1 {name: 猪,age: 2, } 正确的写法…

【AIGC】从CoT到BoT:AGI推理能力提升24%的技术变革如何驱动ChatGPT未来发展

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AIGC | ChatGPT 文章目录 &#x1f4af;前言&#x1f4af;迈向AGI的新跨越&#x1f4af;BoT与CoT的技术对比技术原理差异推理性能提升应用范围和通用性从错误中学习的能力总结 &#x1f4af;BoT的工作流程和机制初始化过程生成推…

LLVM - 编译器前端-llvm:IRBuilder 介绍

一:概述 llvm::IRBuilder 是 LLVM 中的一个重要类,用于方便地构建 LLVM 中间表示(IR)。它提供了一种高层次的接口,使得生成和操作 IR 更加简洁和高效。通过使用 IRBuilder,开发者可以轻松地创建基本块、指令、函数等,而不需要直接操作低级别的 LLVM API。它的主要功能有…