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

news2024/11/16 23:41:47

简介

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

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

描述

组合模式涉及以下角色:

  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.coloradmin.cn/o/1066927.html

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

相关文章

一、Excel VBA 是个啥?

Excel VBA 从入门到出门一、Excel VBA 是个啥&#xff1f;二、Excel VBA 简单使用 &#x1f44b;Excel VBA 是个啥&#xff1f; ⚽️1. Excel 中的 VBA 是什么&#xff1f;⚽️2. 为什么 VBA 很重要&#xff1f;⚽️3. 是否有无代码方法可以在 Excel 中实现工作流程自动化&…

QT基础入门——界面布局和常用控件(四)

前言&#xff1a; 所谓 GUI 界面&#xff0c;归根结底&#xff0c;就是一堆组件的叠加。我们创建一个窗口&#xff0c;把按钮放上面&#xff0c;把图标放上面&#xff0c;这样就成了一个界面。在放置时&#xff0c;组件的位置尤其重要。我们必须要指定组件放在哪里&#xff0c…

2023-IDEA插件推荐

CamelCase 链接 https://plugins.jetbrains.com/plugin/7160-camelcase https://github.com/netnexus/camelcaseplugin 介绍 提供下划线、驼峰等代码风格的切换。快捷键是⇧ ⌥ U / Shift Alt U GsonFormatPlus 链接 https://plugins.jetbrains.com/plugin/14949-gs…

比较好用的在线项目管理系统推荐

好的项目管理系统首先要能满足你在管理项目中的要求&#xff0c;不同的团队规模、不同的项目对项目管理的要求都是不一样的。其次&#xff0c;引入项目管理系统的本身是为了提高管理和协作的效率&#xff0c;因此工具应该是要简单易用的&#xff0c;很多企业引入工具之后形同虚…

十、pygame小游戏开发

目录 一、安装pygame二、pygame快速入门2.1 坐标系认识2.2 创建游戏主窗口2.3 实现图像绘制2.4 游戏循环和游戏时钟2.5 简单动画实现的实现2.6 监听事件2.7 精灵和精灵组三、游戏框架搭建3.1 实现飞机大战主游戏类3.2 完成游戏初始化部分3.3 使用常量代替固定的数值3.4 完成游戏…

VulnHub BREAKOUT

一、信息收集 1.端口扫描 nmap -sS -A 192.168.103.178.24发现开发了80、10000、20000 以及有smb协议 2.查看80端口 右击查看源代码&#xff0c;发现尾部有个密文加密 一看就是 Brainfuck/Ook! 加密&#xff0c;解得&#xff1a;.2uqPEfj3D<Pa-3 3.查看10000端口 是个登…

项目需求分析5大常见问题及解决方案

需求分析过程中&#xff0c;往往容易导致需求不准确和不完整&#xff0c;引起需求频繁变更&#xff0c;导致项目进度延误和成本增加&#xff1b;而需求分析的误解问题&#xff0c;导致交付产品无法满足客户期待&#xff0c;降低用户满意度和资源浪费。 那么在需求分析中&#x…

buuctf-[WUSTCTF2020]CV Maker 文件上传漏洞

打开环境 随便登录注册一下 进入到了profile.php 其他没有什么页面&#xff0c;只能更换头像上传文件&#xff0c;所以猜测是文件上传漏洞 上传一句话木马看看 <?php eval($_POST[a]);?>回显 搜索一下 添加文件头GIF89a。上传php文件 查看页面源代码&#xff0c;看…

使用python利用merge+sort函数对excel进行连接并排序

好久没更新了&#xff0c;天天玩短视频了。现在发现找点学习资料真的好难。 10.1期间偶然拿到一本书 本书是2022年出版的&#xff0c;看了一下不错&#xff0c;根据上面的案例结合&#xff0c;公司经营整合案例&#xff0c;分享一下。 数据内容来源于书中内容&#xff0c;仅供…

Dubbo3应用开发—Dubbo3注册中心(zookeeper、nacos、consul)的使用

Dubbo3注册中心的使用 zookeeper注册中心的使用 依赖引入 <dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-dependencies-zookeeper-curator5</artifactId><version>${dubbo.version}</version><type>p…

MySQL Cluster

文章目录 1.简介2.组成参考文献 1.简介 MySQL Cluster 是官方推出的基于 NDB&#xff08;Network DataBase&#xff09;存储引擎的高可用和可伸缩的分布式数据库系统。 以下是 MySQL NDB Cluster 的主要特点和能力&#xff1a; 高可用&#xff1a;MySQL Cluster 具有内置的高…

python+selenium实现UI自动化(入门篇)

一、基础准备。 python环境安装&#xff0c;参考&#xff1a;CSDN pycharm安装&#xff0c;参考&#xff1a;CSDN 谷歌浏览器驱动配置&#xff0c;参考&#xff1a;CSDN二、新建pycharm项目 截图中&#xff0c;上面是项目地址&#xff08;可以提前在指定位置创建文件夹&#xf…

TenDB Cluster 简介

文章目录 1.简介2.TSpider3.TenDB4.Tdbctl5.TenDB Cluster Operator参考文献 1.简介 TenDB Cluster 是腾讯游戏 CROS DBA 团队提供的 MySQL 分布式关系型数据库解决方案。主要特点包括&#xff1a;透明分库分表、高可用的 MySQL 集群服务&#xff0c;透明及在线的扩容及缩容&a…

AI绘画-Stable Diffusion笔记

软件&#xff1a;Stable Diffusion 视频教程来自 https://www.bilibili.com/video/BV1As4y127HW/?spm_id_from333.337.search-card.all.click 提示词 提示词类别 内容型提示词 人物主题特征&#xff1a; 服饰穿搭&#xff1a;white dress 发型发色&#xff1a;blonde hair,l…

Docker 安装 MongoDB

一、什么是MongoDB MongoDB 是一个基于分布式文件存储的数据库。是一个介于关系数据库和非关系数据库之间的产品&#xff0c;是非关系数据库当中功能最丰富&#xff0c;最像关系数据库的。 二、MongoDB的安装 这里使用docker来安装MongoD 1.docker 拉取mysql镜像 docker pu…

基于SSM+Vue的物流管理系统的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;VueHTML 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 …

Notepad++提取含有特定字符串的行

ctrl M快捷键&#xff0c;进入"标记" 页面 标记所在行–循环查找-- 正则表达式 – 输入关键字 – 全部标记 – Copy Marked Text 关键字格式如下&#xff1a; .*关键字.*ctrl v&#xff0c;粘贴即可。

vue模版语法-{{}}/v-text/v-html/v-once

一、{{}}双括号&#xff1a;用于文本渲染 1、 {{变量名}}:data中返回对象的变量名 2、{{js表达式}}:可以直接进行js表达式处理 3、注意&#xff1a;双大括号中不要写等式书写 二、v-text 指令&#xff0c;用于文本渲染 1、为了解决双大括号渲染数据出现闪烁问题 三、v-cloak …

Mysql bin-log日志恢复数据与物理备份-xtrabackup

主打一个数据备份与恢复 binlog与xtarbackup bin-log日志恢复开启bin-log配置bin-log日志恢复 物理备份-xtrabackup三种备份方式安装xtrabackup备份全量备份增量备份差异备份 bin-log日志恢复 bin-log 日志&#xff0c;就记录对数据库进行的操作&#xff0c;什么增删改的操作全…

uniapp webview和H5通信的三种方式

uniapp可以打包成多个端&#xff0c;再和H5通信的方式中&#xff0c;涉及到uniapp和H5通信&#xff0c;APP和H5通信&#xff0c;小程序和H5通信。其中的h5端分为非uniapp打包的h5和uniapp打包的h5,这两者的区别其实就是uniapp的h5里面已经有了uni这个定义&#xff0c;所以不能再…