09结构型设计模式——组合模式

news2024/9/23 15:26:38

一、组合模式的简介

组合模式(Composite Pattern)是一种结构型设计模式,主要用于处理树形结构中的对象组合问题。它允许你将对象组合成树形结构,以表示部分-整体层次结构。组合模式使得客户端能够统一地对待单个对象和对象组合,从而简化了树形结构的操作。

组合模式的结构图

  1. 组件(Component)

    • 定义了叶子节点和容器节点的共同接口或抽象类。通常包括一些通用的方法,例如operation(),这些方法会被叶子节点和容器节点实现。
  2. 叶子节点(Leaf)

    • 实现了组件接口的具体类,代表树形结构中的最底层元素。叶子节点没有子节点,它们实现了具体的操作逻辑。
  3. 容器节点(Composite)

    • 也实现了组件接口的具体类,代表树形结构中的中间节点。容器节点可以有子节点,这些子节点可以是叶子节点或其他容器节点。容器节点通常包含对子节点的管理功能,例如添加、删除子节点的方法。

组合模式的核心概念

  1. 对象的统一处理

    • 组合模式允许你将对象(叶子节点)和对象组合(容器节点)以相同的方式对待。这意味着客户端可以对叶子节点和容器节点使用相同的操作,而不必关心它们的具体类型。
  2. 部分-整体关系

    • 组合模式主要用于表示“部分”和“整体”之间的关系。整体由部分组成,而部分也可以是整体的一部分。通过这种方式,可以在树形结构中定义和管理层次关系。
  3. 递归结构

    • 组合模式常常使用递归结构,因为树形结构本质上是递归的。一个节点可能包含其他节点,而这些节点又可以包含更多节点。

组合模式的优点

  1. 统一处理

    • 客户端代码可以通过统一的接口处理单个对象和对象组合,从而简化了操作和维护。
  2. 简化代码

    • 组合模式可以将复杂的树形结构操作封装在组件类中,使得客户端代码更简洁、更易于理解。
  3. 灵活性

    • 可以在运行时动态地增加或修改树形结构中的节点。通过组合模式,可以灵活地构建和管理树形结构。
  4. 扩展性

    • 组合模式允许你在不修改现有代码的情况下,轻松地扩展新的节点类型或结构。

二、组合模式的应用场景

1. 文件系统

场景:操作文件和目录,文件系统本质上是一个树形结构,目录包含文件和子目录,子目录也可以包含文件和子目录。

2. 图形用户界面(GUI)

场景:构建图形用户界面时,界面元素(如按钮、文本框、面板)可以组成复杂的层次结构,面板中可以包含其他面板和各种控件。

3. 组织结构管理

场景:管理公司或组织的层级结构,包括员工、部门和公司。公司包含多个部门,每个部门包含员工或其他子部门。

4. 菜单系统

场景:构建复杂的菜单系统,包括菜单项、子菜单和子菜单项,菜单项和子菜单项可以统一处理。

5. 树形结构的数据处理

场景:处理复杂的数据结构,如解析和管理 XML 或 JSON 数据。这些数据结构通常具有嵌套的层次关系。

三、组合模式的设计方法

目录/文件的组合关系(目录包含目录,目录包含文件)

composite.cpp

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

// 文件系统
class FileSystemComponent {
public:
    virtual ~FileSystemComponent() = default;
    virtual void list(int indent = 0) const = 0;
};

// 文件
class File : public FileSystemComponent {
public:
    File(const std::string& name) : name(name) {}
    void list(int indent = 0) const override {
        std::cout << std::string(indent, ' ') << "File: " << name << std::endl;
    }

private:
    std::string name;
};

// 目录
class Directory : public FileSystemComponent {
public:
    Directory(const std::string& name) : name(name) {}
    
    void add(std::shared_ptr<FileSystemComponent> component) {
        children.push_back(component);
    }

    void list(int indent = 0) const override {
        std::cout << std::string(indent, ' ') << "Directory: " << name << std::endl;
        for (const auto& child : children) {
            child->list(indent + 2);
        }
    }

private:
    std::string name;
    std::vector<std::shared_ptr<FileSystemComponent>> children;
};

void doWorking() {
    // 创建文件
    auto file1 = std::make_shared<File>("file1.txt");
    auto file2 = std::make_shared<File>("file2.txt");
    auto file3 = std::make_shared<File>("file3.txt");

    // 创建目录
    auto dir1 = std::make_shared<Directory>("dir1");
    auto dir2 = std::make_shared<Directory>("dir2");
    auto dir3 = std::make_shared<Directory>("dir3");

    // 组装文件系统
    dir1->add(file1);
    dir1->add(file2);

    dir2->add(file3);
    dir2->add(dir1);  // dir2 包含 dir1

    dir3->add(dir2);  // dir3 包含 dir2

    // 列出整个文件系统
    dir3->list();

    return ;
}

int main() {

	doWorking();
	return 0;
}

运行效果

四、总结

组合模式通过提供一个统一的接口来处理单个对象和对象组合,使得客户端能够以一致的方式操作树形结构中的元素,比如composite.cpp的代码设计中接口提供了统一的add()方法模拟目录和文件的包含关系,最后使用list()方法直观显示树形组合结构。组合模式特别适合处理具有部分-整体结构的系统,其中对象可以被递归地组合成树形结构。它使得客户端能够以一致的方式对待单个对象和对象组合,从而简化了代码和操作,提高了系统的灵活性和扩展性。

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

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

相关文章

SEREN MC2电源匹配器控制器Matching Network Controller手侧

SEREN MC2电源匹配器控制器Matching Network Controller手侧

NC 反转链表

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了就去分享给你的码吧。 描述 给定一个单链…

亲测解决Bundler HTTPError Could not fetch specs from

这个问题源于ruby的网站连接不上&#xff0c;解决方法是修改网页地址或者网络配置。 环境 win11 ruby 问题原文 Retrying fetcher due to error (2/4): Bundler::HTTPError Could not fetch specs from https://rubygems.org/ due to underlying error <IO::TimeoutEr…

C# 将Dll嵌入exe中发布

一、制作模版Dll 二、在exe工程中添加Dll 1、添加上述“创建Dll”&#xff0c;并修改属性为&#xff1a;不复制到输出目录的嵌入资源 2、引用“Resource”中的dll文件&#xff0c;并修改属性&#xff1a;不复制到本地 三、添加重载Dll代码 1、添加以下代码 class DependentFi…

Modbus 通信协议详解

目录 一、概述二、Modbus 的作用三、Modbus 的工作原理1、四种数据类型2、三种工作模式3、三类功能码3.1 标志功能码3.2 Modbus 封装接口3.3 异常 4、Modbus 协议层4.1 协议数据单元4.2 访问数据4.3 数据模型寻址4.3.1 数据寻址范围4.3.2 数据地址起始值 4.4 大数据类型4.4.1 位…

频率检测计

前言 频率计是一种用于测量信号频率的仪器。它可以准确地确定电子信号的频率&#xff0c;广泛应用于电子设备的测试和维护中。频率计的工作原理通常包括对输入信号进行采样&#xff0c;并通过内部电路计算信号的周期&#xff0c;从而得到频率值。现代频率计通常具有高精度、高稳…

无线通信代码搬运/复现系列(1) : 重新审视具有每天线功率约束的 MIMO 容量:固定点迭代和交替优化

无线通信代码搬运/复现系列(1) “Revisiting the MIMO Capacity with Per-antenna Power Constraint: Fixed-point Iteration and Alternating Optimization,” IEEE Trans. Wireless Commun., vol. 18, no. 1, pp. 388-401, Jan. 2019 by T. M. Pham, R. Farrell, and L.-N. …

C++入门——05STL

STL&#xff08;Standard Template Library&#xff0c;标准模板库&#xff09;是C标准库的重要组成部分&#xff0c;是一个通用的数据结构和算法库。STL提供了一组经过精心设计的模板类和函数&#xff0c;用于处理各种常见的数据结构&#xff08;如容器&#xff09;和算法&…

六. 部署分类器-preprocess-speed-compare

目录 前言0. 简述1. 案例运行2. 代码分析2.1 main.cpp2.2 preprocess.cpp 3. 补充说明结语下载链接参考 前言 自动驾驶之心推出的 《CUDA与TensorRT部署实战课程》&#xff0c;链接。记录下个人学习笔记&#xff0c;仅供自己参考 本次课程我们来学习课程第六章—部署分类器&…

嵌入式面经篇八——进程线程

文章目录 前言一、进程&线程1、异步 IO 和同步 IO 区别&#xff1f;2、进程间通信方式&#xff1f;3、进程的地址空间模型&#xff1f;4、进程的五种状态分别是?5、子进程从父进程继承的资源有哪些&#xff1f;6、什么是进程上下文、中断上下文&#xff1f;7、如何防止僵尸…

写了一个分页 sql,因为粗心出了 bug 造成了 OOM!

大家好&#xff0c;我是君哥。 最近上完线后&#xff0c;凌晨收到一个生产告警&#xff0c;一个 OOM 异常导致了服务重启。今天来分享一下这个事故。 1.事故现场 事故的代码逻辑并不复杂&#xff0c;从一个大概有 8 万数据的表里面查出数据&#xff0c;汇总后对数据做处理。…

高校宣讲会管理系统--论文pf

TOC springboot370高校宣讲会管理系统--论文pf 第1章 绪论 1.1选题动因 当前的网络技术&#xff0c;软件技术等都具备成熟的理论基础&#xff0c;市场上也出现各种技术开发的软件&#xff0c;这些软件都被用于各个领域&#xff0c;包括生活和工作的领域。随着电脑和笔记本的…

【myz_tools】Python库 myz_tools:Python算法及文档自动化生成工具 - 0.2.0版更新

文章目录 0.2.0 更新内容如下函数generate_2d_combinations_iter函数generate_row_permutations函数calculate_total_permutations函数display_combinations函数evaluate_list_similarity函数check_unique 写在前面关于库库使用库内所有函数目录文件名称: common_maths.py函数部…

ZooKeeper分布式协调系统介绍

1. ZooKeeper概述 1.1 ZooKeeper介绍 ZooKeeper 是 Apache 软件基金会的一个项目&#xff0c;它确实提供了一种非常有用的服务&#xff0c;用于维护分布式系统中的配置信息、命名、提供分布式同步和提供组服务等。它的核心是原子广播和大约一致性模型&#xff0c;这使得它能够…

CCF-GESP五级考级——初等数论,全网最精简的求最大公约数gcd和最小公倍数lcm方法(100%好使)

&#x1f451;一、约数和因数的区别 约数必须在整除的前提下才存在&#xff0c;而因数是从乘积的角度来提出的。如果数与数相乘的积是数&#xff0c;是的因数。 1.约数只能对在整数范围内而言&#xff0c;而因数就不限于整数的范围。 举个栗子&#xff1a;。2和8是16的…

中仕公考:国考往年招录情况对比

2025年国考预计10月中旬启动&#xff0c;11月进行笔试。中仕为大家总结了往年的国考招录情况&#xff0c;希望能给大家一些参考。 2024年计划招录3.96万人。截止到考试结束&#xff0c;共有225.2万人参加了考试&#xff0c;参加考试人数与录用计划数之比约为57:1&#xff0c;2…

CSP-J 2023真题一轮

选择题 阅读题 第1题 第2题 第3题 完善程序 第1题 第2题 答案&#xff1a; 一、单选题 1-5 BDAAC 6-10 BCADA 11-15 ABBAD 二、阅读程序 1&#xff09; 16. √ 17. √ 18. ⅹ 19.A 20.B 2&#xff09; 21. √ 22. ⅹ 23. √ 24. D 25.B 26.D 3&#xff09; 27. √ 28. √ 29…

EasyCVR视频汇聚平台构建远程安防监控:5大亮点解析,助力安防无死角

随着科技的飞速发展&#xff0c;远程安防监控系统已经成为现代社会中不可或缺的一部分&#xff0c;无论是在小区、公共场所还是工业领域&#xff0c;安防监控都发挥着至关重要的作用。而EasyCVR作为一款功能强大的视频监控综合管理平台&#xff0c;其在构建远程安防监控系统方面…

谷歌浏览器下载文件被阻止怎么解除

在工作生活中&#xff0c;我们会使用谷歌浏览器下载各种各样的文件&#xff0c;不过偶尔会遇到文件下载被阻止的情况。为了解决这一问题&#xff0c;本文为大家分享了实用的措施建议&#xff0c;一起来了解一下吧。&#xff08;本文由https://chrome.cmrrs.com/站点的作者进行编…

python爬取豆瓣电影数据

目录 一、背景 二、分析网站 1、ajax请求 三、代码实现 1、导包 2、面向对象实现 3、发送请求 4、解析数据 5、保存数据 6、定义主函数 7、实例化对象运行主函数 8、运行效果 四、以下是全部完整代码 五、报错解决 1、数据库连接报错 2、数据插入报错 一、背景…