组合模式-C++实现

组合模式是一种结构型设计模式,它允许我们将对象组织成树状结构,并以递归的方式处理它们。该模式通过将单个对象和组合对象统一对待,使得客户端可以以一致的方式处理对象集合。

组合模式中有两种角色:组合和组件。组件就是叶子节点,它们没有子组件。组合是包含其他组件的容器节点,可以包含子组合或者叶子节点。

组合模式的核心思想是将对象组织成树状结构,其中单个对象和组合对象都实现了相同的接口或者继承相同的抽象类,这样可以使客户端以递归的方式处理整个对象树,不需要关心处理的节点是叶子节点还是组合节点。

举例:

我们现在要实现一个文件系统,文件系统下有多个目录或者文件,每个目录都会有多个目录和文件。

#pragma once

#include <iostream>
#include <memory>
#include <vector>

// 抽象类
class IFileSystem
{
public:

	virtual ~IFileSystem() {}

	virtual void Display() = 0;
};

// 文件,也就是叶子节点
class File
	: public IFileSystem
{
public:

	File(const std::string& _fileName)
		: fileName_(_fileName)
	{}

	virtual void Display() override
	{
		std::cout << fileName_ << std::endl;
	}

private:

	std::string fileName_;
};

// 目录,也就是组合节点
class Directory
	: public IFileSystem
{
public:

	Directory(const std::string _directoryName)
		: directoryName_(_directoryName)
	{}

	void AddComponment(std::shared_ptr<IFileSystem> _componment)
	{
		components_.emplace_back(_componment);
	}

	virtual void Display() override
	{
		std::cout << directoryName_ << std::endl;

		// 递归处理子节点
		for (auto it : components_)
			it->Display();
	}

private:

	// 目录名字
	std::string directoryName_;

	// 子节点
	std::vector<std::shared_ptr<IFileSystem>> components_;
};

在这个示例中,FileSystemComponent 是一个抽象基类,定义了所有文件系统组件需要实现的操作。File 是一个叶子节点类,代表文件对象,它实现了 Display 方法来显示文件名。Directory 是一个组合节点类,代表目录对象,它除了实现 Display 方法外,还可以通过 AddComponent 方法添加子节点。

不同的是在组合节点目录中,我们有一个存放子节点的容器components_,它存放的就是该目录下的所有组合节点或者叶子节点,以便可以递归处理它们。

测试:

void TestComponment()
{
	// 创建文件系统
	std::shared_ptr<Directory> root = std::make_shared<Directory>("Root");
	// 创建两个目录
	std::shared_ptr<Directory> sub1 = std::make_shared<Directory>("目录1");
	std::shared_ptr<Directory> sub2 = std::make_shared<Directory>("目录2");
	// 创建三个文件
	std::shared_ptr<File> file1 = std::make_shared<File>("文件1");
	std::shared_ptr<File> file2 = std::make_shared<File>("文件2");
	std::shared_ptr<File> file3 = std::make_shared<File>("文件3");

	// 创建树结构
	root->AddComponment(sub1);
	root->AddComponment(sub2);

	// 目录1下面有一个文件
	sub1->AddComponment(file1);
	// 目录2下面有两个文件
	sub2->AddComponment(file2);
	sub2->AddComponment(file3);

	root->Display();
}

测试代码中,我们创建了一个根节点root,它下面有两个目录,其中目录1里有一个文件文件1目录2有两个文件文件2文件3

输出:

Root
目录1
文件1
目录2
文件2
文件3

我们可以看到系统依次输出目录和文件名,它们的树状结构是这样的:
在这里插入图片描述
组合模式遵循以下设计原则:

1、单一职责原则 (Single Responsibility Principle):文件类只负责输出自己的文件名,目录类负责输出自己的目录名和其子节点的所有名称,即每个类应该只有一个责任。

2、开闭原则 (Open-Closed Principle):再给这个文件系统中添加一个组合节点或者子节点我们只需要添加像文件或者目录这样的类即可,即系统应该对扩展开放,对修改关闭。

3、接口隔离原则 (Interface Segregation Principle):客户端没有依赖抽象接口,即客户端不应该依赖于它不需要使用的接口。

4、依赖倒置原则 (Dependency Inversion Principle):文件和目录都依赖抽象接口,即高层模块不应该依赖于低层模块,两者都应该依赖于抽象。

优点:

1、简化客户端代码:客户端可以一致地使用单个对象或组合对象,而不需要区分它们之间的差异。

2、灵活性和可扩展性:可以很容易地增加新的组件,而不会影响现有的组件。

3、对象层次结构的一致性:组合模式让单个对象和组合对象具有相似的操作,使得整个对象层次结构更加统一。

缺点:

1、可能会加重系统的复杂性:在一些场景下,使用组合模式可能会导致系统变得更加复杂,特别是在对象层次结构比较庞大时。

2、可能会降低运行效率:由于组合模式需要通过递归来操作对象层次结构,可能会导致一些性能损耗。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

状态类算法复杂排序输出

对于目标检测任务中对某一类的检测结果进行输出的时候&#xff0c;一般都是无序的&#xff0c;很明显这样子很难满足的我们的需求&#xff0c;我们更喜欢他是这样子输出的&#xff1a; &#x1f447; 我们可以看到——”按顺序输出结果“中的字段是完美的和上面图片中的识别结…

Redis 安装部署

文章目录 1、前言2、安装部署2.1、单机模式2.1.1、通过 yum 安装&#xff08;不推荐&#xff0c;版本老旧&#xff09;2.1.1、通过源码编译安装&#xff08;推荐&#xff09; 2.2、主从模式2.3、哨兵模式2.4、集群模式2.5、其他命令2.6、其他操作系统 3、使用3.1、Java 代码 —…

吉他初学者学习网站搭建系列(4)——如何查询和弦图

文章目录 背景实现ChordDbvexchords 背景 作为吉他初学者&#xff0c;如何根据和弦名快速查到和弦图是一个必不可少的功能。以往也许你会去翻和弦的书籍查询&#xff0c;像查新华字典那样&#xff0c;但是有了互联网后我们不必那样&#xff0c;只需要在网页上输入和弦名&#…

react之ReactRouter的使用

react之ReactRouter的使用 一、环境搭建二、抽象路由模块三、路由导航3.1 声明式导航3.2 编程式导航 四、导航传参4.1 searchParams 传参4.2 params 传参 五 、嵌套路由配置六、默认二级路由七、404页面配置八、俩种路由模式 一、环境搭建 1.创建项目安装依赖 npx create-rea…

2024年美国大学生数学建模竞赛(MCM/ICM)论文写作方法指导

一、前言 谈笑有鸿儒&#xff0c;往来无白丁。鸟宿池边树&#xff0c;僧敲月下门。士为知己者死&#xff0c;女为悦己者容。吴楚东南坼&#xff0c;乾坤日夜浮。剪不断&#xff0c;理还乱&#xff0c;是离愁&#xff0c;别是一番滋味在心头。 重要提示&#xff1a;优秀论文的解…

Matlab 加权均值质心计算(WMN)

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 思路很简单,即将之前的均值中心,引入相关的权重函数(通常与距离有关),以此为每个点进行赋权,最后即可得到一个加权均值中心: 二、实现代码 %% ********<

[二分查找]LeetCode2009 :使数组连续的最少操作数

本文涉及的基础知识点 二分查找算法合集 作者推荐 动态规划LeetCode2552&#xff1a;优化了6版的1324模式 题目 给你一个整数数组 nums 。每一次操作中&#xff0c;你可以将 nums 中 任意 一个元素替换成 任意 整数。 如果 nums 满足以下条件&#xff0c;那么它是 连续的 …

ChatGPT 上线一周年

一年前&#xff0c;ChatGPT 正式上线&#xff0c;这无疑是个革命性的时刻&#xff0c;仅仅 6 周&#xff0c;ChatGPT 用户量达到 1 个亿。 这一年元宇宙作为概念垃圾彻底进入下水道&#xff0c;而 ChatGPT 和 AI 则席卷全球。 仅仅这一年&#xff0c;依托于 ChatGPT&#xff…

SmartSoftHelp8,数据库事务测试工具

SQL数据库事务测试工具 SQL数据库事务回滚测试工具 下载地址&#xff1a; https://pan.baidu.com/s/1zBgeYsqWnSlNgiKPR2lUYg?pwd8888

二分查找:LeetCode2035:将数组分成两个数组并最小化数组和的差

本文涉及的基础知识点 二分查找算法合集 作者推荐 动态规划LeetCode2552&#xff1a;优化了6版的1324模式 题目 给你一个长度为 2 * n 的整数数组。你需要将 nums 分成 两个 长度为 n 的数组&#xff0c;分别求出两个数组的和&#xff0c;并 最小化 两个数组和之 差的绝对…

nodejs微信小程序+python+PHP贵州旅游系统的设计与实现-计算机毕业设计推荐MySQL

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…

巧用MACD精准抄底和逃顶

一、认识MACD MACD又称平滑异同移动平均线&#xff0c;是由美国投资家杰拉尔德阿佩尔在 20 世纪 70 年代末提出的。 MACD 指标的设计基于MA均线原理&#xff0c;是对收盘价进行平滑处理&#xff08;求出加权平均值&#xff09;后的一种趋向类指标。它是股票交易中一种常见的技术…

IDEA2023安装教程(超详细)

文章目录 前言安装IntelliJ IDEA1. 下载IntelliJ IDEA2. 运行安装程序3. 选择安装路径4. 选择启动器设置5. 等待安装完成6. 启动IntelliJ IDEA7. 配置和设置8. 激活或选择许可证9. 开始使用 总结 前言 随着软件开发的不断发展&#xff0c;IntelliJ IDEA成为了许多开发人员首选…

pygame实现贪吃蛇小游戏

import pygame import random# 游戏初始化 pygame.init()# 游戏窗口设置 win_width, win_height 800, 600 window pygame.display.set_mode((win_width, win_height)) pygame.display.set_caption("Snake Game")# 颜色设置 WHITE (255, 255, 255) BLACK (0, 0, 0…

avue-tabs设置默认选中的tab

文章目录 一、问题二、解决三、最后 一、问题 最近在用avue这个UI框架来开发页面&#xff0c;有用到avue-tabs这个tab切换组件。结果竟然发现element-ui中el-tabs的v-model在avue-tabs中竟然是没有用的&#xff0c;无法设置默认选中哪个tab。avue这个基于element-ui开发的UI框…

【计算机网络笔记】802.11无线局域网

系列文章目录 什么是计算机网络&#xff1f; 什么是网络协议&#xff1f; 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能&#xff08;1&#xff09;——速率、带宽、延迟 计算机网络性能&#xff08;2&#xff09;…

制作一个RISC-V的操作系统二-RISC-V ISA介绍

文章目录 ISA的基本介绍啥是ISA为什么要设计ISACISCvsRISCISA的宽度知名ISA介绍 RISC-V历史和特点RISC-V发展RISC-V ISA 命名规范模块化的ISA通用寄存器Hart特权级别Control and Status Register&#xff08;CSR&#xff09;内存管理与保护异常和中断 ISA的基本介绍 啥是ISA …

十大经典系统架构设计面试题

十大经典系统架构设计面试题_架构_程序员石磊_InfoQ写作社区翻译自&#xff1a;https://medium.com/geekculture/top-10-system-design-interview-questions-10f7b5ea123d在我作为微软和Facebhttps://xie.infoq.cn/article/4c0c9328a725a76922f6547ad 任何 SDI 问题的提示 通过…

Elasticsearch:什么是自然语言处理(NLP)?

自然语言处理定义 自然语言处理 (natural language processing - NLP) 是人工智能 (AI) 的一种形式&#xff0c;专注于计算机和人们使用人类语言进行交互的方式。 NLP 技术帮助计算机使用我们的自然交流模式&#xff08;语音和书面文本&#xff09;来分析、理解和响应我们。 自…

OpenCV-Python:计算机视觉介绍

目录 1.背景 2.计算机视觉发展历史 3.计算机视觉主要任务 4.计算机视觉应用场景 5.知识笔记 1.背景 OpenCV是计算机视觉的一个框架&#xff0c;想要学习OpenCV&#xff0c;需要对计算机视觉有一个大致的了解。计算机视觉是指通过计算机技术和算法来模拟人类视觉系统的能力…