C++软件设计模式之组合模式与其他模式的协作举例

组合模式(Composite Pattern)、装饰器模式(Decorator Pattern)、享元模式(Flyweight Pattern)、迭代器模式(Iterator Pattern)和访问者模式(Visitor Pattern)是五种常见的设计模式,它们各自解决不同的问题,但在某些场景下可以相互协作。以下是它们之间的关联以及如何在C++中结合使用这些模式的示例。

组合模式与装饰器模式的关联

组合模式处理对象的层次结构,而装饰器模式处理对象功能的动态扩展。在某些情况下,可以使用装饰器模式来装饰组合模式中的节点,从而在不修改组合结构的情况下扩展其功能。

示例:使用装饰器模式扩展组合模式中的节点
#include <iostream>
#include <vector>// 组合模式部分
class Component {
public:virtual void operation() = 0;virtual ~Component() {}
};class Leaf : public Component {
public:void operation() override {std::cout << "Leaf operation" << std::endl;}
};class Composite : public Component {
public:void add(Component* component) {components.push_back(component);}void operation() override {std::cout << "Composite operation" << std::endl;for (auto& component : components) {component->operation();}}
private:std::vector<Component*> components;
};// 装饰器模式部分
class Decorator : public Component {
protected:Component* component;
public:Decorator(Component* component) : component(component) {}void operation() override {component->operation();}
};class BorderDecorator : public Decorator {
public:BorderDecorator(Component* component) : Decorator(component) {}void operation() override {Decorator::operation();std::cout << "Adding border" << std::endl;}
};int main() {Composite* root = new Composite();root->add(new Leaf());root->add(new Leaf());Composite* subComposite = new Composite();subComposite->add(new Leaf());root->add(subComposite);// 使用装饰器模式扩展组合模式中的节点Component* decoratedRoot = new BorderDecorator(root);decoratedRoot->operation();delete decoratedRoot;return 0;
}

组合模式与享元模式的关联

享元模式通过共享技术来有效地支持大量细粒度的对象。在组合模式中,可以使用享元模式来共享叶子节点或部分组合节点,从而减少内存使用。

示例:使用享元模式共享组合模式中的叶子节点
#include <iostream>
#include <vector>
#include <unordered_map>// 享元模式部分
class Flyweight {
public:virtual void operation() = 0;virtual ~Flyweight() {}
};class ConcreteFlyweight : public Flyweight {
public:void operation() override {std::cout << "ConcreteFlyweight operation" << std::endl;}
};class FlyweightFactory {
public:Flyweight* getFlyweight(const std::string& key) {if (flyweights.find(key) == flyweights.end()) {flyweights[key] = new ConcreteFlyweight();}return flyweights[key];}
private:std::unordered_map<std::string, Flyweight*> flyweights;
};// 组合模式部分
class Component {
public:virtual void operation() = 0;virtual ~Component() {}
};class Leaf : public Component {
public:Leaf(Flyweight* flyweight) : flyweight(flyweight) {}void operation() override {flyweight->operation();}
private:Flyweight* flyweight;
};class Composite : public Component {
public:void add(Component* component) {components.push_back(component);}void operation() override {std::cout << "Composite operation" << std::endl;for (auto& component : components) {component->operation();}}
private:std::vector<Component*> components;
};int main() {FlyweightFactory factory;Composite* root = new Composite();root->add(new Leaf(factory.getFlyweight("leaf1")));root->add(new Leaf(factory.getFlyweight("leaf1"))); // 共享相同的享元对象root->add(new Leaf(factory.getFlyweight("leaf2")));root->operation();delete root;return 0;
}

组合模式与迭代器模式的关联

迭代器模式提供了一种顺序访问聚合对象中各个元素的方法,而不暴露其内部表示。在组合模式中,可以使用迭代器模式来遍历组合结构的节点。

示例:使用迭代器模式遍历组合模式中的节点
#include <iostream>
#include <vector>// 组合模式部分
class Component {
public:virtual void operation() = 0;virtual ~Component() {}
};class Leaf : public Component {
public:void operation() override {std::cout << "Leaf operation" << std::endl;}
};class Composite : public Component {
public:void add(Component* component) {components.push_back(component);}void operation() override {std::cout << "Composite operation" << std::endl;for (auto& component : components) {component->operation();}}// 迭代器模式实现class Iterator {public:Iterator(const std::vector<Component*>& components) : components(components), index(0) {}bool hasNext() {return index < components.size();}Component* next() {return components[index++];}private:std::vector<Component*> components;size_t index;};Iterator* createIterator() {return new Iterator(components);}private:std::vector<Component*> components;
};int main() {Composite* root = new Composite();root->add(new Leaf());root->add(new Leaf());Composite* subComposite = new Composite();subComposite->add(new Leaf());root->add(subComposite);// 使用迭代器模式遍历组合模式的节点Composite::Iterator* iterator = root->createIterator();while (iterator->hasNext()) {iterator->next()->operation();}delete root;delete iterator;return 0;
}

组合模式与访问者模式的关联

访问者模式允许你在不修改已有类层次结构的情况下,定义新的操作。在组合模式中,可以使用访问者模式来对组合结构的节点执行不同的操作。

示例:使用访问者模式对组合模式中的节点执行不同操作
#include <iostream>
#include <vector>// 组合模式部分
class Component {
public:virtual void accept(class Visitor*) = 0;virtual ~Component() {}
};class Leaf : public Component {
public:void accept(Visitor* visitor) override;
};class Composite : public Component {
public:void add(Component* component) {components.push_back(component);}void accept(Visitor* visitor) override;
private:std::vector<Component*> components;
};// 访问者模式部分
class Visitor {
public:virtual void visitLeaf(Leaf* leaf) = 0;virtual void visitComposite(Composite* composite) = 0;
};class PrintVisitor : public Visitor {
public:void visitLeaf(Leaf* leaf) override {std::cout << "Visiting Leaf" << std::endl;}void visitComposite(Composite* composite) override {std::cout << "Visiting Composite" << std::endl;for (auto& component : composite->components) {component->accept(this);}}
};void Leaf::accept(Visitor* visitor) {visitor->visitLeaf(this);
}void Composite::accept(Visitor* visitor) {visitor->visitComposite(this);
}int main() {Composite* root = new Composite();root->add(new Leaf());root->add(new Leaf());Composite* subComposite = new Composite();subComposite->add(new Leaf());root->add(subComposite);// 使用访问者模式对组合模式的节点执行操作PrintVisitor visitor;root->accept(&visitor);delete root;return 0;
}

总结

  • 组合模式:处理对象的层次结构,使得客户端可以统一处理组合结构中的所有对象。
  • 装饰器模式:动态地扩展对象的功能,常用于扩展组合模式中的节点。
  • 享元模式:通过共享技术减少内存使用,常用于共享组合模式中的叶子节点。
  • 迭代器模式:提供顺序访问聚合对象的方法,常用于遍历组合模式的节点。
  • 访问者模式:在不修改已有类层次结构的情况下,定义新的操作,常用于对组合模式的节点执行不同操作。

这些模式可以在不同的场景下相互协作,从而提供更灵活和高效的解决方案。

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

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

相关文章

2686694 - 操作方法:MSEG - DBSQL_REDIRECT_INCONSISTENCY

2686694 - 操作方法&#xff1a;MSEG - DBSQL_REDIRECT_INCONSISTENCY SAP Note, Version: 4, 审批日期: 24.04.2023 显示更改 组件MM-IM-GF对象状态 优先级建议/附加信息对象状态 类别咨询对象状态 审批状态已发布至客户对象状态 更正0对象状态 手动活动0对象状态已成…

嵌入式 FPGA开发

目录 一、引言 二、当前嵌入式 FPGA 开发的现状 三、嵌入式 FPGA 开发的优势 四、嵌入式 FPGA 的应用领域 1. 通信系统 2. 数字信号处理 3. 视频图像处理 4. 高速接口设计 5. 人工智能 6. IC 设计与 PCB 设计类比 五、嵌入式 FPGA 未来发展趋势 六、结论 一、引言 …

工业AI质检 AI质检智能系统 尤劲恩(上海)信息科技有限公司

来的现代化工厂&#xff0c;将逐步被无人化车间取代&#xff0c;无人工厂除了产线自动化&#xff0c;其无人质检将是绕不开的话题。尤劲恩致力于帮助工业制造领域上下游工厂减员增效、提高品质效率&#xff0c;真正实现无人质检IQC/IPQC/OQC的在线质检系统。分析生产环节真实品…

Angular v19 (三):增量水合特性详解 - 什么是水合过程?有哪些应用场景?与 Qwik 相比谁更胜一筹?- 哪个技术好我就学哪个,这就是吸心大法吧

Angular在其最新版本 v19 中引入了增量水合&#xff08;Incremental Hydration&#xff09;这一特性。这一更新引发了开发者们广泛的讨论&#xff0c;特别是在优化首屏加载速度和改善用户体验方面。本文将详解水合过程的概念、增量水合的应用场景&#xff0c;以及它与类似框架如…

[STM32]从零开始的STM32 FreeRTOS移植教程

一、前言 如果能看到这个教程的话&#xff0c;说明大家已经学习嵌入式有一段时间了。还记得嵌入式在大多数时候指的是什么吗&#xff1f;是的&#xff0c;我们所说的学习嵌入式大部分时候都是在学习嵌入式操作系统。从简单的一些任务状态机再到复杂一些的RTOS&#xff0c;再到最…

Vivado程序固化到Flash

在上板调试FPGA时&#xff0c;通常使用JTAG接口下载程序到FPGA芯片中&#xff0c;FPGA本身是基于RAM工艺的器件&#xff0c;因此掉电后会丢失芯片内的程序&#xff0c;需要重新烧写程序。但是当程序需要投入使用时不能每一次都使用JTAG接口下载程序&#xff0c;一般FPGA的外围会…

医疗废物检测

3809总图像数 数据集分割 训练组80&#xff05; 3030图片 有效集20&#xff05; 779图片 测试集&#xff05; 0图片 标签 预处理 自动定向&#xff1a; 已应用 调整大小&#xff1a; 拉伸至 640x640 增强 未应用任何增强。 注射器 手术刀 输液管 医用手套 医用口罩 血渍 数据集…

如何进行JOIN优化

如何进行JOIN优化 简单来说&#xff0c;JOIN是MySQL用来进行联表操作的&#xff0c;用来匹配两个表的数据&#xff0c;筛选并合并符合我们要求的结果集&#xff0c;但使用了Join我们一般会对它多一点关注&#xff0c;在java开发手册中&#xff0c;禁止三个表以上关联使用Join&…

uniapp使用扩展组件uni-data-select出现的问题汇总

前言 不知道大家有没有学习过我的这门课程那&#xff0c;《uniCloud云开发Vue3版本官方推荐用法》&#xff0c;这么课程已经得到了官方推荐&#xff0c;想要快速上手unicloud的小伙伴们&#xff0c;可以学习一下这么课程哦&#xff0c;不要忘了给一键三连呀。 在录制这门课程…

Spring 自调用事务失效分析及解决办法

前言 博主在写公司需求的时候&#xff0c;有一个操作涉及到多次对数据库数据的修改。当时就想着要加 Transactional注解来声名事务。并且由于一个方法中有太多行了&#xff0c;于是就想着修改数据库的操作单独提取出来抽象成一个方法。但这个时候&#xff0c;IDEA 提示我自调用…

黑马2024AI+JavaWeb开发入门Day03-Maven-单元测试飞书作业

视频地址&#xff1a;哔哩哔哩 讲义作业飞书地址&#xff1a;飞书 作业比较简单&#xff0c;随便写了写 package org.example;import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.ju…

常见的数据结构---数组、链表、栈的深入剖析

目录 一、数组&#xff08;Array&#xff09; 二、链表&#xff08;Linked List&#xff09; 三、栈&#xff08;Stack&#xff09; 四、总结 数据结构是算法的基石&#xff0c;是程序设计的核心基础。不同的数据结构适用于不同的场景和需求&#xff0c;选择合适的数据结构能…

KAN-Transfomer——基于新型神经网络KAN的时间序列预测

1.数据集介绍 ETT(电变压器温度)&#xff1a;由两个小时级数据集&#xff08;ETTh&#xff09;和两个 15 分钟级数据集&#xff08;ETTm&#xff09;组成。它们中的每一个都包含 2016 年 7 月至 2018 年 7 月的七种石油和电力变压器的负载特征。 traffic(交通) &#xff1a;描…

【C++算法】20.二分查找算法_x 的平方根

文章目录 题目链接&#xff1a;题目描述&#xff1a;解法C 算法代码&#xff1a;图解 题目链接&#xff1a; 69. x 的平方根 题目描述&#xff1a; 解法 暴力解法&#xff1a; 如果x17 从1&#xff0c;2&#xff0c;3&#xff0c;4&#xff0c;5......这些数里面找他们的平方…

阿里云人工智能平台(PAI)免费使用教程

文章目录 注册新建实例交互式建模(DSW)注册 注册阿里云账号进行支付宝验证 新建实例 选择资源信息和环境信息,填写实例名称 资源类型需要选择公共资源,才能使用资源包进行抵扣。目前每月送250计算时。1 * NVIDIA A10 8 vCPU 30 GiB 1 * 24 GiB1 * NVIDIA V100 8 vCPU 32 Gi…

Three.js 相机视角的平滑过渡与点击模型切换视角

在 Three.js 中&#xff0c;实现相机视角的平滑过渡和点击模型切换到查看模型视角是一个常见且有用的功能。这种效果不仅能提升用户体验&#xff0c;还能为场景互动添加更多的动态元素。 1. 基本设置 首先&#xff0c;我们需要创建一个基本的 Three.js 场景&#xff0c;包括相…

【Web】0基础学Web—html基本骨架、语义化标签、非语义化标签、列表、表格、表单

0基础学Web—html基本骨架、语义化标签、非语义化标签、列表、表格、表单 html基本骨架语义化标签图片属性a链接 非语义化标签特殊符号标签 列表无序列表结果展示 有序列表结果展示 定义列表结果展示 表格table属性tr属性结果展示 表单单标签form属性input属性selecttextareabu…

判断一个数字是否为质数。-多语言

目录 C 语言实现 Python 实现 Java 实现 Js 实现 题目&#xff1a;判断一个数字是否为质数。 程序分析&#xff1a;质数&#xff08;prime number&#xff09;又称素数&#xff0c;有无限个。一个大于1的自然数&#xff0c;除了1和它本身外&#xff0c;不能被其他自然数整…

iwebsec 靶场 —— SSRF 漏洞

免责声明 本博客文章仅供教育和研究目的使用。本文中提到的所有信息和技术均基于公开来源和合法获取的知识。本文不鼓励或支持任何非法活动&#xff0c;包括但不限于未经授权访问计算机系统、网络或数据。 作者对于读者使用本文中的信息所导致的任何直接或间接后果不承担任何…

docker-compose 升级

官方下载地址&#xff1a; https://github.com/docker/compose/releases 下载完放到kali root目录下 # mv docker-compose-Linux-x86_64 /usr/local/bin/docker-compose # chmod x /usr/local/bin/docker-compose # docker-compose --version