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.总结

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

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

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

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

相关文章

[江科大STM32] 第五集快速建立STM32工程模板——笔记

保存&#xff0c;进去选芯片型号&#xff0c;我们是F10C8T6 一个MD&#xff0c;还有所有.c.h 这里所有文件 这里所有文件

Elasticsearch:基础概念

一、什么是Elasticsearch Elasticsearch是基于 Apache Lucene 构建的分布式搜索和分析引擎、可扩展数据存储和矢量数据库。它针对生产规模工作负载的速度和相关性进行了优化。使用 Elasticsearch 可以近乎实时地搜索、索引、存储和分析各种形状和大小的数据。Elasticsearch 是…

安卓播放器TVbox或影视仓软件如何链接到xiaoya小雅超集?很详细的教程

前言 这里咱们说的安卓播放器软件指的是这个&#xff1a; 还有这个&#xff1a; 这两个软件只是个壳&#xff0c;你需要做的仅仅是把需要的内容填写到对应的位置即可。 开始这个教程之前&#xff0c;你需要先部署好小雅&#xff0c;如果没有部署小雅&#xff0c;这个教程基本…

Datawhale AI冬令营 动手学AI Agent

背景——什么是Agent 在人工智能领域&#xff0c;agent可以指一个能够感知环境并作出决策以实现特定目标的系统。比如&#xff0c;一个聊天机器人&#xff08;chatbot&#xff09;就是一个agent&#xff0c;它能够理解用户的输入并给出相应的回复。 学习目标 学会使用百宝箱平…

如何在IDEA一个窗口中导入多个项目

一般在IDEA窗口中想导入一个新项目&#xff0c;会提示我们在当前窗口还是新窗口。如果选新窗口&#xff0c;就会新打开一个窗口&#xff0c;此时新窗口里面只有新导入的项目。 而为了浏览起来更方便&#xff0c;需要实现在IDEA一个窗口中导入多个项目。具体步骤如下&#xff1…

面试经典问题 —— 链表之返回倒数第k个节点(经典的双指针问题)

目录 原题思路代码实现小结 原题 leetcode链接 &#xff1a; https://leetcode.cn/problems/kth-node-from-end-of-list-lcci/description/ 思路 这题就是典型的双指针母题 第一个指针先移动k步&#xff0c;然后第二个指针再从头开始&#xff0c;这个时候这两个指针同时移动&am…

VMware安装配置

1、官网下载VMware16 &#xff08;1&#xff09;进入VMware官网https://www.vmware.com/cn.html&#xff0c;之后点击下载里的Workstation Pro&#xff1a; &#xff08;2&#xff09;之后选择你要下载的VMware的版本&#xff0c;找到合适的下载&#xff0c;我这里以Windows系…

【文献精读笔记】Explainability for Large Language Models: A Survey (大语言模型的可解释性综述)(五)

****非斜体正文为原文献内容&#xff08;也包含笔者的补充&#xff09;&#xff0c;灰色块中是对文章细节的进一步详细解释&#xff01; 五、 解释评估&#xff08;Explanation Evaluation&#xff09; 在前面的章节中&#xff0c;我们介绍了不同的解释技术和它们的用途&#…

SQL 中的 EXISTS

我们先从 SQL 中最基础的 WHERE 子句开始。 比如下面这条 SQL 语句&#xff1a; 很显然&#xff0c;在执行这条 SQL 语句的时候&#xff0c;DBMS 会扫描 Student 表中的每一条记录&#xff0c;然后把符合 Sdept IS 这个条件的所有记录筛选出来&#xff0c;并放到结果集里面去…

C语言链表通关文牒0.5

之前排序创建链表那里用的是哨兵法&#xff0c;但是有局限性&#xff0c;这里介绍一个补充&#xff0c;不创建第一个空节点进行排序 NODE *create() {int val;NODE *head NULL; // 初始化头指针为NULLNODE *pC NULL; // 初始化指针&#xff0c;用于遍历链表while(1) {pri…

GAN对抗生成网络(一)——基本原理及数学推导

1 背景 GAN(Generative Adversarial Networks)对抗生成网络是一个很巧妙的模型&#xff0c;它可以用于文字、图像或视频的生成。 例如&#xff0c;以下就是GAN所生成的人脸图像。 2 算法思想 假如你是《古董局中局》的文物造假者&#xff08;Generator,生成器&#xff09;&a…

基于Python的携程旅游景点数据分析与可视化

基于Python的携程旅游景点数据分析与可视化 爬取景点、价格、开放状态、评论、热度、优惠政策等信息。 功能列表 指定城市爬取支持登录支持筛选支持评论爬取支持数据存在数据库支持生成Excel支持可视化 部分效果演示 爬取的旅游景点信息 生成Excel 指定城市爬取 可视化 部门…

SQL-leetcode-197. 上升的温度

197. 上升的温度 表&#xff1a; Weather ---------------------- | Column Name | Type | ---------------------- | id | int | | recordDate | date | | temperature | int | ---------------------- id 是该表具有唯一值的列。 没有具有相同 recordDate 的不同行。 该表包…

等待事件 ‘latch: row cache objects‘ 说明及解决方法

早上刚来的时候&#xff0c;收到zabbix 数据库连接数增长的告警&#xff0c;同时应用负责人也说查询很慢、很卡 查看该时间段 最多的等待事件 SELECT event,COUNT(1) num FROM V$ACTIVE_SESSION_HISTORY A WHERE A.SAMPLE_TIME BETWEEN TO_DATE(2025-01-02 09:00:00, YYYY-M…

HAL 库------中断相关函数

HAL_SuspendTick();是对SysTick中CTRL寄存器中TICKINT位清0 HAL_ResumeTick(); 刚好与上面函数相反&#xff0c;对SysTick中CTRL寄存器中TICKINT位置1&#xff0c;恢复stick中断。

IDEA开发Java应用的初始化设置

一、插件安装 如下图所示&#xff1a; 1、Alibaba Java Coding Guidelines 2.1.1 阿里开发者规范&#xff0c;可以帮忙本地自动扫描出不符合开发者规范的代码&#xff0c;甚至是代码漏洞提示。 右击项目&#xff0c;选择《编码规约扫描》&#xff0c;可以进行本地代码规范扫…

QT-------------多线程

实现思路 QThread 类简介&#xff1a; QThread 是 Qt 中用于多线程编程的基础类。可以通过继承 QThread 并重写 run() 方法来创建自定义的线程逻辑。新线程的执行从 run() 开始&#xff0c;调用 start() 方法启动线程。 掷骰子的多线程应用程序&#xff1a; 创建一个 DiceThre…

在C语言基础上的C++(深入理解类和对象)

1&#xff1a;构造函数 1&#xff1a;为什么使用构造函数 由于类的封装性&#xff0c;一般来说&#xff0c;数据成员是不能被外界访问的&#xff0c;所以对象的数据成员的初始化工作就给共有函数来完成了。如果定义了构造函数&#xff0c;那么只要对象一建立&#xff0c;就可…

ESP32_H2-ESP32_H2(IDF)学习系列-安装官方组件

1、 在VS Code项目工程中添加IDF组件注册表中的组件十分便捷。您只需按下“CtrlShiftP”快捷键快速进入命令面板&#xff0c;或者通过菜单栏的“查看”选项&#xff0c;选择“命令面板”来打开它。随后&#xff0c;在命令面板中输入“ESP-IDF: Show Component Registry”即可展…

【UE5】UnrealEngine源码构建2:windows构建unreal engine 5.3.2

参考大神知乎的文章:UE5 小白也能看懂的源码编译指南 据说会耗费400G的空间。 代码本身并不大,可能是依赖特别多,毕竟看起来UE啥都能干,核心还是c++的, 【UE5】UnrealEngine源码构建1:tag为5.3.2源码clone 本着好奇+ 学习的态度,想着也许有机会能更为深入的熟悉UE的机制…