当前位置: 首页 > news >正文

C++ 设计模式:装饰模式(Decorator Pattern)

链接:C++ 设计模式
链接:C++ 设计模式 - 桥接模式

装饰模式(Decorator Pattern)是一种结构型设计模式,它允许向一个现有的对象添加新的功能,同时又不改变其结构。装饰模式通过创建一个装饰类来包装原始类,从而在保持类接口不变的情况下,动态地扩展对象的功能。

1.适用场景

  1. 需要动态扩展对象的功能:当需要在运行时动态地为对象添加功能,而不是在编译时确定这些功能时。
  2. 功能可以按需组合:当对象的功能可以通过多种方式组合,并且这些组合是动态变化的。
  3. 避免类爆炸:如果使用继承来扩展功能,会导致类的数量急剧增加,因为每种功能组合都需要一个新的子类。装饰模式通过组合装饰器来避免这个问题。

2.实现步骤

  1. 定义组件接口:定义一个接口,描述基本组件的行为。
  2. 实现具体组件:实现基本组件类,提供组件的基本功能。
  3. 定义装饰器基类:创建一个装饰器基类,继承自组件接口,并持有一个组件对象的引用。
  4. 实现具体装饰器:实现具体装饰器类,继承自装饰器基类,并在扩展功能的方法中调用被装饰的组件对象的方法。
  5. 动态组合装饰器:在客户端代码中,动态地将装饰器组合在一起,扩展组件的功能。

3.代码示例

以机器人的任务扩展作为示例。

3.1.组件接口

class Robot {public:virtual ~Robot() = default;virtual void performTask() = 0;
};

3.2.基本组件

// 具备基本功能
class BasicRobot : public Robot {public:void performTask() override { std::cout << "Performing basic tasks." << std::endl; }
};

3.3.装饰器基类

// 继承自组件接口
class RobotDecorator : public Robot {public:RobotDecorator(std::shared_ptr<Robot> robot) : decoratedRobot(robot) {}void performTask() override { decoratedRobot->performTask(); }protected:std::shared_ptr<Robot> decoratedRobot;
};

3.4.具体装饰器

// 具体装饰器1:添加播放音乐功能
class MusicPlayerDecorator : public RobotDecorator {public:MusicPlayerDecorator(std::shared_ptr<Robot> robot) : RobotDecorator(robot) {}void performTask() override {RobotDecorator::performTask();playMusic();}private:void playMusic() { std::cout << "Playing music." << std::endl; }
};
// 具体装饰器2:添加拍照功能
class CameraDecorator : public RobotDecorator {public:CameraDecorator(std::shared_ptr<Robot> robot) : RobotDecorator(robot) {}void performTask() override {RobotDecorator::performTask();takePhoto();}private:void takePhoto() { std::cout << "Taking a photo." << std::endl; }
};
// 具体装饰器3:添加导航功能
class NavigationDecorator : public RobotDecorator {public:NavigationDecorator(std::shared_ptr<Robot> robot) : RobotDecorator(robot) {}void performTask() override {RobotDecorator::performTask();navigate();}private:void navigate() { std::cout << "Navigating to the destination." << std::endl; }
};

3.5.动态组合

int main() {// 创建一个基本机器人std::shared_ptr<Robot> basicRobot = std::make_shared<BasicRobot>();// 添加播放音乐功能std::shared_ptr<Robot> musicPlayerRobot = std::make_shared<MusicPlayerDecorator>(basicRobot);// 添加播放音乐和拍照功能std::shared_ptr<Robot> cameraRobot = std::make_shared<CameraDecorator>(musicPlayerRobot);// 添加播放音乐和导航功能std::shared_ptr<Robot> fullFeaturedRobot = std::make_shared<NavigationDecorator>(musicPlayerRobot );// 执行任务std::cout << "Basic Robot:" << std::endl;basicRobot->performTask();std::cout << "\nMusic Player Robot:" << std::endl;musicPlayerRobot->performTask();std::cout << "\nCamera Robot:" << std::endl;cameraRobot->performTask();std::cout << "\nFull Featured Robot:" << std::endl;fullFeaturedRobot->performTask();return 0;
}

4.总结

装饰模式和桥接模式的区别:

  • 装饰模式:动态地给对象添加职责,而不改变对象的接口。它通过创建一系列装饰器类来实现这些职责的扩展,从而在运行时灵活地扩展对象的功能。
  • 桥接模式:将抽象部分与实现部分分离,使它们可以独立变化。它通过将抽象和实现放在不同的类层次结构中,并通过组合将它们连接起来,从而提高系统的灵活性和可扩展性。

相关文章:

C++ 设计模式:装饰模式(Decorator Pattern)

链接&#xff1a;C 设计模式 链接&#xff1a;C 设计模式 - 桥接模式 装饰模式&#xff08;Decorator Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其结构。装饰模式通过创建一个装饰类来包装原始类&…...

排序算法之快速排序、归并排序

目录 快速排序归并排序的意义 快速排序 思维步骤 具体思想 测试样例解释 代码实现 归并排序 思维步骤 具体思想 测试样例解释 代码实现 快速排序归并排序的意义 快速排序和归并排序不仅仅是一种方法&#xff0c;更重要的是其作为一种算法而节省时间&#xff0c;在…...

一文读懂变分自编码(VAE)

一文读懂变分自编码(VAE) 概述 变分自编码器&#xff08;Variational Autoencoder, VAE&#xff09;是一种生成模型&#xff0c;用于学习数据的潜在表示并生成与原始数据分布相似的新数据。它是一种概率模型&#xff0c;通过结合深度学习和变分推断的思想&#xff0c;解决了传…...

【每日学点鸿蒙知识】webview性能优化、taskpool、热更新、Navigation问题、调试时每次都卸载重装问题

1、HarmonyOS webview页面第二次&#xff0c;第三次打开感觉和第一次打开速度差不多&#xff0c;有优化吗&#xff0c;或者有没有webview秒开方案之类的&#xff1f; 目前没有webview秒开的方案&#xff0c;针对web场景的优化参考一下文档&#xff1a;https://developer.huawe…...

周记-唐纳德的《计算机程序设计艺术》

用代码生成代码 开发一个协议&#xff0c;字段有些多&#xff0c;每个字段是QT的属性&#xff0c;需要写Q_PROPERTY&#xff0c;一个一个编辑的话比较繁琐&#xff0c;耗费时间。后来就用代码生成了头文件和源文件&#xff0c;get和set还有signal函数&#xff0c;内容基本都是…...

AR 模型的功率谱

功率谱密度&#xff08;Power Spectral Density, PSD&#xff09;的表达式是从信号的自相关函数和系统的频率响应推导出来的&#xff0c;特别是对于 AR&#xff08;Auto-Regressive&#xff0c;自回归&#xff09;模型。以下是推导的过程&#xff1a; 1. AR 模型的定义&#xf…...

抖音小程序登录(前端通过tt.login获取code换取openId)

抖音小程序登录 抖音开放平台小程序登录&#xff1a; https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/tutorial/basic-ability/microapp-login 前端(通过tt.login获取code) 流程 静默登录依赖小程序 API tt.login&#xff0c;把tt.loginsuccess 回调…...

Linux 更改Jenkins使用其他账户启动

Linux 更改Jenkins使用其他账户启动 步骤一&#xff1a;修改 Jenkins 配置文件1. 编辑 Jenkins 的 systemd 服务文件&#xff1a;2. 在编辑器中添加以下内容&#xff1a;3. 保存并退出编辑器 步骤二&#xff1a;更改 Jenkins 目录的权限步骤三&#xff1a;重新加载 systemd 配置…...

117.【C语言】数据结构之排序(选择排序)

目录 1.知识回顾 2.分析 设想的思路 代码 执行结果 ​编辑 错误排查和修复 详细分析出错点 执行结果 3.正确的思路 4.其他问题 1.知识回顾 参见42.5【C语言】选择排序代码 点我跳转 2.分析 知识回顾里所提到的文章的选择排序一次循环只比一个数字,和本文接下来要…...

读书系列2024

认知类 1、《人生没有太晚的开始》&#xff1a; 作者摩西奶奶。 书中经典语录&#xff1a;“与其着急忙慌地不知从何开始&#xff0c;不如一切都慢慢来&#xff0c;开始并坚持了&#xff0c;总会有结果的那一天。喜欢一件事&#xff0c;你就慢慢去做吧。” 2、《忏悔录》托尔…...

如何快速又安全的实现端口转发【Windows MAC linux通用】

背景 有很多程序是在虚拟机上运行的&#xff0c;返回的url 又是127.0.0.1。在个人电脑上调试需要解决这个问题。端口转发是一个不错的方法 可能的解决办法&#xff1a; 1.修改程序&#xff0c;返回虚拟机的ip &#xff08;要改代码&#xff0c;换虚拟机还要再改代码&#xf…...

OpenGL变换矩阵和输入控制

在前面的文章当中我们已经成功播放了动画&#xff0c;让我们的角色动了起来&#xff0c;这一切变得比较有意思了起来。不过我们发现&#xff0c;角色虽然说是动了起来&#xff0c;不过只是在不停地原地踏步而已&#xff0c;而且我们也没有办法通过键盘来控制这个角色来进行移动…...

51单片机学习笔记——找不到REG52.H头文件,点亮一个LED

创建工程 将STC型号导入keil并使用 STC可以从官网下载&#xff0c;也可我这的网盘&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1bO85DPN3IFaXGhiKSwyOrA?pwd7f4h 提取码&#xff1a;7f4h 打开STC&#xff0c;选择“keil仿真设置”&#xff0c;选择“添加型号和头…...

07 基于OpenAMP的核间通信方案

引言 ZYNQ7020有两个CPU核心&#xff0c;这两个核心可以采用SMP或AMP方式进行调度&#xff0c;当采用AMP方式进行调度时核0和核1可以运行不同的操作系统&#xff0c;如核0运行Linux系统&#xff0c;提供有些复杂的用户交互工作&#xff0c;核1运行实时操作系统&#xff0c;对设…...

Ubuntu升级ssh版本到9.8

方案一&#xff1a;实测只有8.9有漏洞不推荐 1、更新软件包列表 sudo apt update 2、查找可用版本 apt-cache policy openssh-server 3、 选择版本 sudo apt install openssh-server1:9.8p1-<具体版本号> 4、 重启 sudo systemctl restart ssh 5、验证版本 /usr/sbin/ss…...

git设置项目远程仓库指向github的一个仓库

要将你的Git项目设置为指向GitHub上的远程仓库&#xff0c;你需要执行以下步骤&#xff1a; 创建GitHub仓库&#xff1a; 登录到你的GitHub账户。点击右上角的 “” 号&#xff0c;选择 “New repository” 创建一个新的仓库。填写仓库的名称&#xff0c;可以添加描述&#xff…...

【实战示例】面向对象的需求建模

前言 博主准备写一个以面向对象为核心思想的软件需求建模、领域建模的系列&#xff0c;总结一整套可落地的DDD的打法&#xff0c;前面几篇文章论述了如何进行面向对象的需求建模&#xff0c;本文将以一个简单的购物商城的需求来演示如何进行面向对象的需求建模。 面向对象的需…...

平方数的判断不用sqrt()函数

//判断一个数是不是平方数&#xff0c;13…&#xff08;2*m-1&#xff09;m*mn #include<stdio.h> int main(){ int n; scanf("%d",&n); int i; for(i1;n>0;i2){ nn-1; } if(n0){ printf("YES!\n"); …...

node.js之---回调函数

什么是回调函数&#xff1f; 为什么会有回调函数&#xff1f; 回调函数的特性 回调函数的应用场景 怎么解决回调地狱 什么是回调函数&#xff1f; 回调函数是一个函数&#xff0c;他作为参数传递给另外一个函数&#xff0c;并且会在另外一个函数执行完毕之后被调用&#…...

浏览器http缓存问题

一、什么是浏览器缓存 浏览器将请求过的资源&#xff08;html、js、css、img&#xff09;等&#xff0c;根据缓存机制&#xff0c;拷贝一份副本存储在浏览器的内存或者磁盘上。如果下一次请求的url相同时则根据缓存机制决定是读取内存或者磁盘上的数据还是去服务器请求资源文件…...

编写一个简单的引导加载程序(bootloader)

编写一个简单的引导加载程序&#xff08;bootloader&#xff09;通常用于嵌入式系统或自定义操作系统。这里&#xff0c;我将为你提供一个基于x86架构的简单汇编语言 bootloader 示例。这个 bootloader 将会在启动时打印一条消息到屏幕上。 使用 NASM 汇编器来编写这个 bootlo…...

Three.js 字体

在 Three.js 中&#xff0c;我们可以通过 FontLoader 加载字体&#xff0c;并结合 TextGeometry 创建 3D 文本。加载字体是因为字体文件包含了字体的几何信息&#xff0c;例如字体的形状、大小、粗细等&#xff0c;而 TextGeometry 则是根据字体信息生成 3D 文本的几何体。 在…...

Jenkins 构建流水线

在 Linux 系统上安装 Jenkins 服务&#xff0c;以及配置自动化构建项目 前置准备环境&#xff1a;docker、docker-compose、jdk、maven 一、环境搭建 1. Jenkins 安装 &#xff08;1&#xff09;拉取镜像 # 安装镜像包&#xff0c;默认安装最新版本 docker pull jenkins/jen…...

ES 磁盘使用率检查及处理方法

文章目录 1. 检查原因2. 检查方法3. 处理方法3.1 清理数据3.2 再次检查磁盘使用率 1. 检查原因 磁盘使用率在 85%以下&#xff0c;ES 可正常运行&#xff0c;达到 85%及以上会影响 PEIM 数据存储。 在 ES 磁盘分配分片控制策略中&#xff0c;为了保护数据节点的安全&#xff0…...

【回溯】LeetCode经典题目总结:组合、排列、子集、分割、N皇后、单词搜索

回溯 组合问题组合总和全排列子集分割回文串N皇后电话号码的字母组合单词搜索括号生成 组合问题 给定两个整数 n 和 k&#xff0c;返回 1 … n 中所有可能的 k 个数的组合。 示例: 输入: n 4, k 2 输出: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ] 树形结构&#xff1…...

uniapp开发小程序内嵌h5页面,video视频两边有细小黑色边框

1.问题如图 2.原因分析 是否为设置上述属性呢&#xff1f; 设置了&#xff0c;但是仍然有黑边。经过选中页面元素分析后&#xff0c;判断video元素本身就有这种特点&#xff0c;就是视频资源无法完全铺满元素容器。 3.解决方案...

Ubuntu meson使用

一 下载pip3 &#xff0c;使用pip3下载 meson sudo apt install python3 sudo apt install python3-pip二 下载 nanjia sudo apt-get install ninja-build三 测试 meson 使用 1 同一个目录下创建两个文件 main.c #include<stdio.h> int main() {printf("meson t…...

实用技巧:关于 AD修改原理图库如何同步更新到有原理图 的解决方法

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/144738332 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV…...

算法排序算法

文章目录 快速排序[leetcode 215数组中的第K个最大元素](https://leetcode.cn/problems/kth-largest-element-in-an-array/)分析题解快速排序 桶排序[leetcode 347 前K个高频元素](https://leetcode.cn/problems/top-k-frequent-elements/)分析题解 快速排序 leetcode 215数组…...

植物大战僵尸杂交版3.0.2版本

更新内容 植物大战僵尸杂交版3.0.2版本的更新内容如下&#xff1a; • 修复BUG&#xff1a; • 游戏内贴图错乱的BUG。 • 无尽模式卡死的BUG。 • 卡牌模仿者的一系列BUG。 • 干扰车可能同时出现多辆的BUG。 • 冒险模式部分关卡无法过关的BUG。 • 新增内容&#xf…...

Kafka数据迁移全解析:同集群和跨集群

文章目录 一、同集群迁移二、跨集群迁移 Kafka两种迁移场景&#xff0c;分别是同集群数据迁移、跨集群数据迁移。 一、同集群迁移 应用场景&#xff1a; broker 迁移 主要使用的场景是broker 上线,下线,或者扩容等.基于同一套zookeeper的操作。 实践&#xff1a; 将需要新添加…...

自动化测试模型(一)

8.8.1 自动化测试模型概述 在自动化测试运用于测试工作的过程中&#xff0c;测试人员根据不同自动化测试工具、测试框架等所进行的测试活动进行了抽象&#xff0c;总结出线性测试、模块化驱动测试、数据驱动测试和关键字驱动测试这4种自动化测试模型。 线性测试 首先&#…...

selenium(三)

总结 一、web基础 html、dom对象、javascript基本语法二、元素定位&#xff1a; find_element(定位方式) 八大定位方式&#xff1a;id、name、class、tag_name、class_name、link_text、partial_link_text、xpath、cssxpath://标签名[属性名值 and/or 属性名值]//标签名[tex…...

7.若依参数设置、通知公告、日志管理

参数设置 对系统中的参数进行动态维护。 关闭验证码校验功能 打开页面注册功能 需要修改前端页面代码 通知公告 促进组织内部信息传递 若依只提供了一个半成品&#xff0c;只实现了管理员可以添加通知公告。 日志管理 追踪用户行为和系统运行状况。 登录日志 和操作日志…...

vsftpd虚拟用户及其权限配置

目录 一、应用场景二、配置过程1、安装软件2、新建本地用户3、修改vsftpd的配置文件4、新建虚拟用户目录5、配置虚拟用户&#xff08;1&#xff09;创建虚拟用户列表文件&#xff08;2&#xff09;生成虚拟用户数据库&#xff08;3&#xff09;配置pam认证&#xff08;4&#…...

Android使用辅助服务AccessibilityService实现自动化任务

Android 辅助服务&#xff08;AccessibilityService&#xff09;旨在帮助具有视觉、身体或年龄相关限制的用户更轻松地使用 Android 设备和应用。通过辅助服务&#xff0c;可以将一些人工操作自动化&#xff0c;从而解放用户的双手。 因此我们可以使用它来实现一些自动化任务&a…...

brupsuite的基础用法常用模块(1)

proxy模块&#xff1a; Options: 设置代理端口&#xff0c;默认为8080端口&#xff0c;若8080端口被占用可在该界面更改代理端口. HTTP history: 拦截的历史请求&#xff0c;右键可做更多操作&#xff0c;很多操作与其他模块有关。&#xff08;清除历史的话右键选择clear p…...

基础的基础之 pillow与opencv相比的特点与优缺点比较

Pillow 和 OpenCV 都是人工智能图像处理的必不可少的常用库&#xff0c;但它们有各自的特点和适用场景。 以下是它们的主要特点、优缺点以及适用场景的对比&#xff1a; 1. Pillow&#xff08;Python Imaging Library&#xff09; Pillow 是一个轻量级的图像处理库&#xff0…...

代码随想录算法训练营第51期第32天 | 理论基础、509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯

理论基础 动态规划&#xff1a;dp&#xff0c;每一个状态都是由上个状态推导出来的&#xff0c;因为我是先写完三道题再看理论的&#xff0c;所以有点感概&#xff1b; 确定dp数组&#xff08;dp table&#xff09;以及下标的含义确定递推公式dp数组如何初始化确定遍历顺序举…...

街景主观感知1:街景图片两两对比程序

目录 1、为什么不用place pluse 2.0数据集&#xff1f;2、街景主观感知两两对比程序2.1 总框架2.2 两两对比程序流程2.2.1 准备数据集&#xff08;即街景图片&#xff09;2.2.2 数据集采用组合的思想构建排列前的两两对比csv2.2.3 两两对比程序使用 3、其他数据处理/程序/指导&…...

vue在action中调用action的函数

以下是在 Vue2 中一个 Vuex 的 action 中调用另一个 action 中的函数的解决思路&#xff1a; 首先&#xff0c;确保你已经在 Vue 项目中正确配置了 Vuex 状态管理。在 Vuex 的 actions 对象中定义不同的 action 函数。当需要在一个 action 中调用另一个 action 时&#xff0c;…...

探索 Java 静态变量(static)的奥秘

目录 一、静态变量初印象 &#xff08;一&#xff09;什么是静态变量 &#xff08;二&#xff09;静态变量的特点 二、静态变量的使用场景 &#xff08;一&#xff09;共享数据 &#xff08;二&#xff09;全局常量 &#xff08;三&#xff09;工具类中的变量 三、静态…...

Excel for Finance 07 `FV PV` 函数

Excel 的 FV 函数用于计算一笔投资在未来的价值&#xff0c;基于固定的利率和定期付款。这是一个金融函数&#xff0c;常用来分析储蓄计划、贷款、或投资的增长。 语法&#xff1a; FV(rate, nper, pmt, [pv], [type])参数说明&#xff1a; rate&#xff08;必需&#xff09;&…...

【GUI-PyQt5】简介

1. 简介 GUI&#xff1a;带图形的用户接口程序&#xff0c;也就是桌面应用。 2. 分类 2.1 基本窗口控件 QMainWindowQwidgetQlabelQLineEdit菜单工具栏 2.2 高级组件 QTableViewQListView容器多线程 2.3 布局管理 QBoxLayoutQGridLayoutQFormLayout嵌套布局 2.4 信号与…...

CMSeasy;大米CMS漏洞复现

一、越权漏洞 pikachu-Over permission 水平越权 ⽔平越权&#xff1a;指攻击者尝试访问与他拥有相同权限的⽤户资源。 登录lucy 查看lucy个人信息 在lucy页面修改usernamelili 可以跳转lili的个人信息页面 pikachu-Over permission 垂直越权 垂直越权&#xff1a;通过低权…...

【CSS in Depth 2 精译_093】16.2:CSS 变换在动效中的应用(上)—— 图标的放大和过渡效果的设置

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第五部分 添加动效 ✔️【第 16 章 变换】 ✔️ 16.1 旋转、平移、缩放与倾斜 16.1.1 变换原点的更改16.1.2 多重变换的设置16.1.3 单个变换属性的设置 16.2 变换在动效中的应用 ✔️ 16.2.1 放大图…...

代码随想录算法【Day5】

DAY5 1.熟悉哈希表的数据结构&#xff1a;数组、map和set&#xff0c;使用方法、使用场景 2.哈希表应用场景&#xff1a;解决给你一个元素&#xff0c;判断它在集合里是否出现过。 242.有效的字母异位词 本题用数组解决的。 class Solution { public:bool isAnagram(strin…...

工程师如何平衡工作和生活?

在快节奏的社会环境中&#xff0c;工程师面临着高强度的工作压力和长时间的工作需求&#xff0c;要做到工作和生活的平衡&#xff0c;确实不容易。然而&#xff0c;通过一些策略和改变工作方式&#xff0c;可以有效缓解压力&#xff0c;找到平衡点。以下是一些建议&#xff1a;…...

若依数据权限控制

效果 新建用户 表结构 sys_role_dept 这张表的存在。是为了实现数据权限自定义的功能 service层 mapper层 流程...

C++ 设计模式:抽象工厂(Abstract Factory)

链接&#xff1a;C 设计模式 链接&#xff1a;C 设计模式 - 工厂方法 链接&#xff1a;C 设计模式 - 原型模式 链接&#xff1a;C 设计模式 - 建造者模式 抽象工厂&#xff08;Abstract Factory&#xff09;是一种创建型设计模式&#xff0c;它提供一个接口&#xff0c;用于创…...