【C++设计模式之组合模式:结构型】分析及示例

简介

组合模式是一种结构型设计模式,它能够将对象组合成树形结构以表示“整体-部分”的层次结构,并且能够使用相同的方式处理单个对象和组合对象。组合模式使得客户端可以一致地处理单个对象和组合对象,无需关心具体的对象类型。

组合模式将对象组织成树型结构,其中树的节点可以是单个对象或者组合对象。通过将对象以树形的方式组合,可以将单个对象和组合对象一视同仁。这种方式使得客户端无需区分单个对象和组合对象,可以递归地处理整个树结构,从而简化了客户端代码。

描述

组合模式涉及以下角色:

  1. 组件(Component):是组合模式中的树节点接口,声明了可以对子节点进行操作的方法,定义了组合对象和叶子对象的共有接口。
  2. 组合(Composite):是组合模式中的非叶子节点类,实现了组件接口,并保存了一个子节点的列表。组合对象可以包含其他组合对象或叶子对象。
  3. 叶子(Leaf):是组合模式中的叶子节点类,实现了组件接口,表示组合对象中的单个对象。

原理

组合模式的原理是将组合对象和叶子对象统一处理,客户端无需区分对待。组合对象中可以包含其他组合对象或叶子对象,这种递归结构可以无限扩展。

类图

在这里插入图片描述

1、Component:组合模式中的“根节点”,可以是接口、抽象类、普通类,该类中定义了其子类的所有共性内容,并且该类中还存在着用于访问和管理它子部件的方法。
2、Leaf:组合中的叶子节点,也就是最末端的节点,该节点下不会再有子节点。
3、Composite:非叶子节点,它的作用是存储子部件,并且在Composite中实现了对子部件的相关操作。

示例

假设有一个文件系统,在文件系统中,有文件夹(组合对象)和文件(叶子对象)。文件夹可以包含其他文件夹或文件,而文件本身不能包含其他对象。可以使用组合模式来处理文件系统中的对象。

在示例中,有三个主要类:

  1. Component(组件):表示组合模式中的树节点,定义了可以对子节点进行操作(如添加、删除、打印等)的接口。
  2. Composite(组合):表示组合模式中的非叶子节点,实现了组件接口,并保存了一个子节点的列表。
  3. Leaf(叶子):表示组合模式中的叶子节点,实现了组件接口,表示组合对象中的单个对象。

C++示例代码:

#include<iostream>
#include<string>
#include<vector>using namespace std;// 组件接口
class Component {
public:virtual void add(Component* component) = 0;virtual void remove(Component* component) = 0;virtual void print() = 0;
};// 组合类
class Composite : public Component {
private:string name;vector<Component*> children;public:Composite(const string& name) : name(name) {}void add(Component* component) override {children.push_back(component);}void remove(Component* component) override {for (auto it = children.begin(); it != children.end(); ++it) {if (*it == component) {children.erase(it);break;}}}void print() override {cout << "Folder: " << name << endl;for (auto child : children) {child->print();}}
};// 叶子类
class Leaf : public Component {
private:string name;public:Leaf(const string& name) : name(name) {}void add(Component* component) override {cout << "Cannot add to a leaf." << endl;}void remove(Component* component) override {cout << "Cannot remove from a leaf." << endl;}void print() override {cout << "File: " << name << endl;}
};int main() {Component* root = new Composite("root");Component* folder1 = new Composite("folder1");Component* folder2 = new Composite("folder2");Component* file1 = new Leaf("file1");Component* file2 = new Leaf("file2");Component* file3 = new Leaf("file3");root->add(folder1);root->add(folder2);folder1->add(file1);folder1->add(file2);folder2->add(file3);root->print();delete root;delete folder1;delete folder2;delete file1;delete file2;delete file3;return 0;
}

输出结果

Folder: root
Folder: folder1
File: file1
File: file2
Folder: folder2
File: file3

解释

在示例中,使用组合模式创建了一个文件系统的树形结构。树的根节点是一个组合对象,包含了两个子节点(文件夹)。每个文件夹又包含了一些子节点(文件或其他文件夹)。通过使用组合模式,可以统一处理所有的节点,无论是文件夹还是文件,都可以使用相同的方式进行操作。

结论

组合模式提供了一种处理整体-部分结构的方式,使得客户端代码可以统一处理单个对象和组合对象。通过使用组合模式,可以实现树形结构的组织和操作,从而更好地管理复杂的对象结构。

应用场景

  • 处理树形结构的场景,例如文件系统、组织结构等。
  • 需要统一处理单个对象和组合对象的场景,例如图形界面中的组件布局、菜单系统等。
  • 需要递归地处理对象的场景,例如目录结构的遍历、文件搜索等。
  • 需要实现树形操作的场景,例如代码抽象语法树的操作。

总之,组合模式可以使得客户端无需区分单个对象和组合对象,可以统一地处理对象的层次结构。它提供了一种灵活且可扩展的方式来处理整体-部分结构,适用于需要处理层次结构的场景。

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

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

相关文章

回归预测 | MATLAB实现PSO-SVR粒子群优化支持向量机回归多输入单输出预测

回归预测 | MATLAB实现PSO-SVR粒子群优化支持向量机回归多输入单输出预测 目录 回归预测 | MATLAB实现PSO-SVR粒子群优化支持向量机回归多输入单输出预测预测效果基本介绍模型描述程序设计预测效果 <

12.1 使用键盘鼠标监控钩子

本节将介绍如何使用Windows API中的SetWindowsHookEx和RegisterHotKey函数来实现键盘鼠标的监控。这些函数可以用来设置全局钩子&#xff0c;通过对特定热键挂钩实现监控的效果&#xff0c;两者的区别在于SetWindowsHookEx函数可以对所有线程进行监控&#xff0c;包括其他进程中…

手机投屏电脑软件AirServer5.6.3.0最新免费版本下载

随着智能手机的普及&#xff0c;越来越多的人喜欢用手机观看视频、玩游戏、办公等。但是&#xff0c;有时候手机屏幕太小&#xff0c;不够清晰&#xff0c;也不方便操作。这时候&#xff0c;如果能把手机屏幕投射到电脑上&#xff0c;就可以享受更大的视野&#xff0c;更流畅的…

SpringMVC的视图

文章目录 1. ThymeleafView2. 转发视图3. 重定向视图4. 视图控制器view-controller5. 总结6. 荐书 SpringMVC中的视图是View接口&#xff0c;视图的作用渲染数据&#xff0c;将模型Model中的数据展示给用户SpringMVC视图的种类很多&#xff0c;默认有转发视图和重定向视图 当工…

【Node.js】NPM 和 package.json

NPM npm 是 Node.js 的包管理工具&#xff0c;基于命令行&#xff0c;用于安装、升级、移除、管理依赖项。 常用命令&#xff1a; npm init&#xff1a;初始化一个新的 npm 项目&#xff0c;创建 package.json 文件。&#xff08;括号里为默认值&#xff09; description&am…

如何保证 RabbitMQ 的消息可靠性?

项目开发中经常会使用消息队列来完成异步处理、应用解耦、流量控制等功能。虽然消息队列的出现解决了一些场景下的问题&#xff0c;但是同时也引出了一些问题&#xff0c;其中使用消息队列时如何保证消息的可靠性就是一个常见的问题。如果在项目中遇到需要保证消息一定被消费的…

DRM全解析 —— CRTC详解(1)

本文参考以下博文&#xff1a; Linux内核4.14版本——drm框架分析(4)——crtc分析 特此致谢&#xff01; 1. 简介 CRTC实际上可以拆分为CRTC。CRT的中文意思是阴极摄像管&#xff0c;就是当初老电视上普遍使用的显像管&#xff08;老电视之所以都很厚&#xff0c;就是因为它…

最全解决docker配置kibana报错 Kibana server is not ready yet

问题复现&#xff1a; 在浏览器输入http://192.168.101.65:5601/ 访问kibana报错 Kibana server is not ready yet 问题报错&#xff1a; 首先查看kibana的日志 docker logs kibana 看到报错如下&#xff1a; {"type":"log","timestamp":&q…

基于BERT模型进行文本处理(Python)

基于BERT模型进行文本处理(Python) 所有程序都由Python使用Spyder运行。 对于BERT&#xff0c;在运行之前&#xff0c;它需要安装一些环境。 首先&#xff0c;打开Spyder。其次&#xff0c;在控制台中单独放置要安装的&#xff1a; pip install transformers pip install tor…

cvpr24写作模板pdfLaTex编译器注意点小结

文章目录 1 更改作者显示 Anonymous CVPR submission2 \label标签的作用3 换行符// 与换列符&4 \medskip5 首行缩进6 插入图片6.1 单幅图片6.2 并排显示 Reference https://cvpr.thecvf.com/Conferences/2024 1 更改作者显示 Anonymous CVPR submission 这一行开头加上% …

C++设计模式-装饰器(Decorator)

目录 C设计模式-装饰器&#xff08;Decorator&#xff09; 一、意图 二、适用性 三、结构 四、参与者 五、代码 C设计模式-装饰器&#xff08;Decorator&#xff09; 一、意图 动态地给一个对象添加一些额外的职责。就增加功能来说&#xff0c;Decorator模式相比生成子…

嵌入式养成计划-35------C++绪论------C++数据类型------array容器------命名空间

七十三、 工具QT 73.1 安装步骤 73.2 什么是 Qt Qt 是一个跨平台的 C图形用户界面应用程序框架。 它为应用程序开发者提供建立艺术级图形界面所需的所有功能。 它是完全面向对象的&#xff0c;很容易扩展&#xff0c;并且允许真正的组件编程。 73.3 Qt 的优点 跨平台&…