突破编程 C++ 设计模式(组合模式)详尽攻略

news2024/9/21 0:40:17

在软件开发中,设计模式为程序员提供了解决特定问题的最佳实践。设计模式不仅提高了代码的可复用性和可维护性,还能帮助团队更好地进行协作。在这篇文章中,我们将深入探讨组合模式——一种结构型设计模式。

组合模式允许你将对象组合成树形结构来表示“部分-整体”的层次关系。组合模式使得客户端对单个对象和组合对象的使用具有一致性,这种一致性简化了对复杂树形结构的操作。

1. 组合模式的基本概念

组合模式的核心思想是通过树形结构来实现对象的组合。这种模式非常适用于表示具有部分-整体关系的对象,例如:

  • 文件系统中的文件与文件夹
  • 组织结构图中的员工和部门

当我们需要对一个复杂对象进行管理时,组合模式便提供了一种简洁有效的解决方案。

1.1 组成部分

组合模式通常包含以下几个组成部分:

  • Component(组件):定义所有具体对象和组合对象的接口。
  • Leaf(叶子节点):具体实现的对象,代表树形结构的最下层。
  • Composite(组合节点):包含叶子节点和其他组合节点的对象,真正实现“部分-整体”的结构。

2. 组合模式的结构图

3. 组合模式的优缺点

3.1 优点

  • 简化树形结构的处理:组合模式允许客户端对单个对象和组合对象进行相同的操作,简化了树形结构的处理。
  • 灵活性:新增或删除树形结构中的节点相对容易,代码的可扩展性增强。

3.2 缺点

  • 过度使用:过度使用组合模式可能使系统变得复杂,尤其在层次结构较深时。
  • 性能问题:如果有大量的层级结构,可能会影响性能。

4. 实际操作案例

接下来,通过一个实际案例来展示如何在 C++ 中实现组合模式。

4.1 需求描述

假设我们正在开发一个文件系统的模拟,希望实现一个文件夹和文件的结构。每个文件夹可以包含多个文件和子文件夹,而每个文件夹和文件都可以统一处理。

4.2 类设计

我们将构建以下类:

  • File 类:表示文件。
  • Folder 类:表示文件夹。
  • FileSystemComponent 基类:定义了文件和文件夹的共同接口。

4.3 代码实现

以下是组合模式在 C++ 中的实现代码:

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

// Component 类
class FileSystemComponent {
public:
virtual void display(int depth) = 0; // 纯虚函数
virtual ~FileSystemComponent() = default; // 虚析构函数
};

// Leaf 类
class File : public FileSystemComponent {
private:
std::string name;

public:
File(const std::string& name) : name(name) {}

void display(int depth) override {
std::cout << std::string(depth, '-') << name << std::endl; // 打印文件名
}
};

// Composite 类
class Folder : public FileSystemComponent {
private:
std::string name;
std::vector<std::shared_ptr<FileSystemComponent>> children; // 存储子节点

public:
Folder(const std::string& name) : name(name) {}

void add(const std::shared_ptr<FileSystemComponent>& component) {
children.push_back(component); // 添加子节点
}

void display(int depth) override {
std::cout << std::string(depth, '-') << name << std::endl; // 打印文件夹名
for (const auto& child : children) {
child->display(depth + 2); // 递归调用显示子节点
}
}
};

// 示例使用
int main() {
// 创建文件夹与文件
auto root = std::make_shared<Folder>("Root");
auto folder1 = std::make_shared<Folder>("Folder1");
auto folder2 = std::make_shared<Folder>("Folder2");

auto file1 = std::make_shared<File>("File1.txt");
auto file2 = std::make_shared<File>("File2.txt");
auto file3 = std::make_shared<File>("File3.txt");

// 构造层次结构
root->add(folder1);
root->add(folder2);
folder1->add(file1);
folder1->add(file2);
folder2->add(file3);

// 显示文件结构
root->display(0);

return 0;
}

4.4 代码解析

  • Component 类:定义了接口以及一个虚析构函数,确保派生类的正确析构。

  • File 类:实现了 FileSystemComponent 接口,表示文件并重写 display 方法以显示文件名。

  • Folder 类:也是 FileSystemComponent 的子类,能够管理文件和文件夹。add 方法用于添加子节点。

  • display 方法:根据深度递归显示文件和文件夹的层次结构。

  • main 函数:构建文件系统的实例并调用 display 方法。

4.5 运行效果

当运行该程序时,输出将会是:

Root
--Folder1
----File1.txt
----File2.txt
--Folder2
----File3.txt

5. 如何正常使用组合模式

组合模式的优雅之处在于其简单和灵活。然而,使用该模式时需要注意以下几点:

  1. 合理设计递归层次:确保组合结构不会过深,以避免性能问题。
  2. 明确职责:清晰定义组件的角色,确保 Leaf 和 Composite 类的职责清晰。
  3. 避免不必要的复杂性:在简单场景下不必使用组合模式,保持设计的简洁性。

组合模式在处理树形结构时提供了一个强大而灵活的框架。通过将对象组合成部分-整体的结构,它简化了复杂对象的管理。尽管组合模式提供了许多优势,但使用时仍需考虑到潜在的复杂性。

在这篇文章中,我们从理论到实践全面探讨了组合模式在 C++ 中的实现,同时提供了一个简单的文件系统示例来展示其应用。如果您想在您的项目中实现类似的结构,组合模式将是一个非常合适的选择。

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

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

相关文章

哪里能免费申请IP SSL证书

一、选择可信赖的证书颁发机构 首先&#xff0c;需要选择一个可信赖的证书颁发机构&#xff08;CA&#xff09;。知名的CA机构如JoySSL、Symantec、GlobalSign等提供IP SSL证书服务。这些机构能够提供符合国际标准的SSL证书&#xff0c;确保数据传输的安全性和服务器的身份验证…

Docker 安装 SqlServer

摘要&#xff1a;我们工作当中经常需要拉取多个数据库实例出来做集群&#xff0c;做测试也好&#xff0c;通过 Docker 拉取 SqlServer 镜像&#xff0c;再通过镜像运行多个容器&#xff0c;几分钟就可以创建多个实例&#xff0c;效率是相当的高。 1. docker 拉取镜像 注意&am…

C++与OpenCV联袂打造:智能视觉识别技术的实践与探索

C与OpenCV联袂打造&#xff1a;智能视觉识别技术的实践与探索 1. 环境设置与准备工作1.1 安装OpenCV和配置开发环境1.1.1 下载OpenCV1.1.2 安装OpenCVWindows系统Linux系统 1.1.3 配置OpenCV库 1.2 C编译器的选择与配置1.2.1 Windows系统1.2.2 Linux系统1.2.3 编译器配置 1.3 选…

浏览器中的开源SQL可视化工具:sqliteviz

sqliteviz&#xff1a; 在浏览器中&#xff0c;即刻开启数据可视化之旅。- 精选真开源&#xff0c;释放新价值。 概览 sqliteviz是一个专为数据可视化而设计的单页离线优先PWA&#xff0c;它利用了现代浏览器技术&#xff0c;让用户无需安装任何软件即可在本地浏览器中进行SQL…

助力外骨骼机器人动力学分析

目录 一、动力学分析 二、拉格朗日方程 三、参考文献 一、动力学分析 动力学是考虑引起运动所需要的力&#xff0c;使执行器作用的力矩或施加在操作臂上的外力使操作臂按照这个动力学方程运动。 目前机器人动力学分析中主要采用牛顿-欧拉动力学方程和拉格朗日动力学方程 […

Leetcode面试经典150题-13.罗马数字转整数

解法都在代码里&#xff0c;不懂就留言或者私信&#xff0c;这个是相对简单点的&#xff0c;感觉会在低职级面试的时候考 class Solution {/**罗马数字转整数还是比较简单的&#xff0c;基本思路&#xff1a;把罗马数字字符串转成字符数组同时创建一个int型数组&#xff0c;遍…

直线公理使初等数学一直将各异直线误为同一线 ——数集相等定义凸显初数一直将各异假R误为R

黄小宁&#xff08;通讯&#xff1a;广州市华南师大南区9-303 510631&#xff09; [摘要]任何图≌自己这一几何最起码常识凸显初等数学一直将无穷多各异直线&#xff08;平面&#xff09;误为同一线&#xff08;面&#xff09;。数集相等的定义凸显&#xff1a;初数应有几何起码…

linux文件——文件系统——文件系统深度理解、学习inode

前言&#xff1a;本篇内容讲解文件系统的细节问题。 在本篇内容中&#xff0c; 我们在学习文件系统的过程中&#xff0c; 我们可以理解inode的原理&#xff0c; 理解如何在文件系统的概念下新建文件&#xff0c; 删除文件&#xff0c; 查找文件&#xff0c; 修改文件等等问题。…

商圣集团:数字创新,引领智慧生活新篇章

在全球化经济不断演进的大潮中&#xff0c;数字经济已成为推动社会进步的关键引擎&#xff0c;重塑着我们的生产与生活模式。商圣集团&#xff0c;以服务社会、创新驱动为核心价值观&#xff0c;致力于利用数字化技术&#xff0c;为个人和企业带来高效、便捷的服务体验&#xf…

【高阶数据结构】秘法(一)——并查集:探索如何高效地管理集合

前言&#xff1a; 前面我们已经学习了简单的数据结构&#xff0c;包括栈与队列、二叉树、红黑树等等&#xff0c;今天我们继续数据结构的学习&#xff0c;但是难度上会逐渐增大&#xff0c;在高阶数据结构中我们要学习的重点是图等 目录 一、并查集的原理 二、并查集的基本操作…

嘉兴银行业绩上涨却市值下滑,新任行长背后的辛酸

撰稿|芋圆 2024年3月6日&#xff0c;秦山核电有限公司&#xff08;以下简称“泰山核电”&#xff09;在上海联合产权交易所转让其所持有的嘉兴银行股份有限公司&#xff08;下称“嘉兴银行”&#xff09;的全部股份630万股的&#xff0c;占嘉兴银行总股本的0.3272%&#xff0c…

【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)

&#x1f31f;&#x1f31f;作者主页&#xff1a;ephemerals__ &#x1f31f;&#x1f31f;所属专栏&#xff1a;C 目录 前言 一、类的概念及定义 1. 类的定义格式 2. 访问限定符 二、类域 三、类的实例化--对象 1. 实例化的概念 2. 对象的内存大小 四、this指针 …

Vue——认识day02

此处接上一篇文章Vue——初识Vue开始&#xff0c;欢迎大家。 目录 1.MVVM模型 2.Object.defineproperty方法 3.数据代理简介 4.Vue中的数据代理 总结 1.MVVM模型 MVVM模型是一种软件架构模式&#xff0c;用于将用户界面&#xff08;View&#xff09;&#xff0c;业务逻辑&…

牛客周赛 Round 35 (A~G)

本次A~D较为简单&#xff0c;E是一道很好的构造题&#xff0c;FG主要就是考察组合数和约数个数 A.小红的字符串切割 思路 &#xff1a;签到题 void solve() {string s;cin>>s;int lens.size();cout<<s.substr(0,len/2)<<endl<<s.substr(len/2); }B.小…

搭建面向切面编程项目

此项目在整合Mybatis基础上修改&#xff0c;可参考主页的整合Mybatis文章 注解版本 第一步 引入maven坐标 <!-- 切面编程所需jar包--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId>…

Chapter 04 Vue指令(下)

欢迎大家订阅【Vue2Vue3】入门到实践 专栏&#xff0c;开启你的 Vue 学习之旅&#xff01; 文章目录 前言一、指令修饰符二、v-bind对于样式操作的增强三、v-model应用于表单元素 前言 在 Vue.js 中&#xff0c;指令是带有 v- 前缀的特殊属性&#xff0c;不同属性对应不同的功…

[原理理解] Swin Transformer相对位置编码理解

文章目录 简述相对位置编码的意义直观理解注意力相对位置获取必要性当前位置初步获取利用广播机制获取相对位置索引XY获取最后相对位置1获取最后相对位置2最终的相对位置值嵌入 简述 在看Swin Transformer的时候&#xff0c;一开始在相对位置编码这一块的理解上卡壳了挺久&…

27 Combobox组件

Tkinter ttk.Combobox 组件使用指南 ttk.Combobox 是 Tkinter 的一个高级控件&#xff0c;它结合了文本框和下拉列表的功能&#xff0c;允许用户从预定义的选项列表中选择一个值。ttk 模块是 Tkinter 的一个扩展&#xff0c;提供了更现代的控件外观和行为。以下是对 ttk.Combo…

hyperf json-rpc

安装 安装docker hyperf 安装 hyperf-rpc-server-v8 &#xff08;服务端&#xff09; docker run --name hyperf-rpc-server-v8 \ -v /www/docker/hyperf-rpc-server:/data/project \ -w /data/project \ -p 9508:9501 -it \ --privileged -u root \ --entrypoint /bin/sh \…

港口行业大数据BI建设方案(24页PPT)

方案简介&#xff1a; 港口行业BI建设方案旨在通过数据整合、分析、可视化及智能化决策支持等手段&#xff0c;提升港口运营效率与管理水平。它的建设实施有利推动港口数字化转型、是提升竞争力的关键举措。通过构建高效、智能的BI系统&#xff0c;港口企业能够实现对运营数据…