当前位置: 首页 > news >正文

篇九:组合模式:树形结构的力量

篇九:“组合模式:树形结构的力量”

开始本篇文章之前先推荐一个好用的学习工具,AIRIght,借助于AI助手工具,学习事半功倍。欢迎访问:http://airight.fun/。

另外有2本不错的关于设计模式的资料,分享出来与大家学习参考。
链接:https://pan.baidu.com/s/1RmhQF_o1CdK8U7s5KeILog?pwd=xc6d
提取码:xc6d

设计模式是软件开发中的重要组成部分,组合模式是结构型设计模式中的一种。组合模式旨在将对象组织成树形结构,使得用户可以以统一的方式处理单个对象和组合对象。通过组合模式,我们可以更加灵活地构建复杂的树形结构,从而实现了对象的递归组合。在C++中,组合模式广泛应用于处理树形结构的场景,让我们一起探讨其核心概念和用途,并演示在C++中如何应用组合模式来构建树形结构。

1. 组合模式的核心概念和用途:
组合模式是结构型设计模式,其核心概念在于将对象组织成树形结构,由树根(树的顶层对象)递归组合其子节点(叶子节点或其他组合节点)。组合模式允许用户以统一的方式处理单个对象和组合对象,无需关心具体处理的是哪种类型的对象。

组合模式的用途如下:

  • 构建复杂树形结构:组合模式允许用户以递归的方式构建复杂的树形结构,将对象和组合对象以统一的方式组织起来。
  • 统一处理对象:组合模式允许用户以统一的方式处理单个对象和组合对象,无需区分具体对象类型。

2. 在C++中应用组合模式构建树形结构:

a. 定义抽象组件类:

// Component.h
#include <string>class Component {
public:virtual ~Component() {}virtual void operation() const = 0;virtual void add(Component* component) {}virtual void remove(Component* component) {}virtual Component* getChild(int index) const { return nullptr; }virtual std::string getName() const { return ""; }
};

b. 创建叶子节点类:

// Leaf.h
#include <iostream>
#include "Component.h"class Leaf : public Component {
public:explicit Leaf(std::string name) : name_(std::move(name)) {}void operation() const override {std::cout << "Leaf " << name_ << " operation" << std::endl;}std::string getName() const override {return name_;}private:std::string name_;
};

c. 创建组合节点类:

// Composite.h
#include <iostream>
#include <vector>
#include "Component.h"class Composite : public Component {
public:explicit Composite(std::string name) : name_(std::move(name)) {}void operation() const override {std::cout << "Composite " << name_ << " operation" << std::endl;for (const auto& component : components_) {component->operation();}}void add(Component* component) override {components_.push_back(component);}void remove(Component* component) override {auto it = std::find(components_.begin(), components_.end(), component);if (it != components_.end()) {components_.erase(it);}}Component* getChild(int index) const override {if (index >= 0 && index < components_.size()) {return components_[index];}return nullptr;}std::string getName() const override {return name_;}private:std::string name_;std::vector<Component*> components_;
};

d. 使用组合模式构建树形结构:

// main.cpp
#include "Leaf.h"
#include "Composite.h"int main() {Component* root = new Composite("Root");Component* leaf1 = new Leaf("Leaf1");Component* leaf2 = new Leaf("Leaf2");root->add(leaf1);root->add(leaf2);Component* subComposite = new Composite("SubComposite");Component* leaf3 = new Leaf("Leaf3");subComposite->add(leaf3);root->add(subComposite);root->operation();delete root;delete leaf1;delete leaf2;delete leaf3;delete subComposite;return 0;
}

在上述示例中,我们首先定义了抽象组件类Component,其中包含了对操作的抽象接口和对子节点的增删查操作。然后,我们创建了叶子节点类Leaf,表示树的叶子节点,以及组合节点类Composite,表示树的组合节点。组合节点类中包含了一个std::vector来存储子节点。

main.cpp中,我们创建了树的根节点root,以及两个叶子节点leaf1leaf2。然后,我们将leaf1leaf2添加到根节点root中。接着,我们创建了一个子组合节点subComposite,并将叶子节点leaf3添加到subComposite中。最后,我们将subComposite添加到根节点root中,并调用rootoperation()方法来执行操作。

3. 组合模式的代码解析:

  • 组合模式通过将对象组织成树形结构,实现了对对象的递归组合。树的根节点作为组合节点,其子节点可以是叶子节点或其他组合节点,从而构建了复杂的树形结构。
  • 抽象组件类定义了操作的抽象接口和对子节点的增删查操作,叶子节点类表示树的叶子节点,组合节点类表示树的组合节点。
  • 组合模式允许用户以统一的方式处理单个对象和组合对象,无需关心具体处理的是哪种类型的对象。用户可以通过组合模式以递归的方式构建复杂的树形结构,并统一处理树的所有节点。

**4. 总结:
组合模式是一种非常有用的设计模式,特别适用于构建树形结构或部分整体层次结构的场景。通过使用组合模式,我们可以简化对树形结构的操作,统一处理叶子节点和组合节点,提高代码的可维护性和可扩展性。

在实际开发中,组合模式经常用于处理复杂的对象组织关系。例如,在图形编辑器中,我们可以使用组合模式来处理图形元素的组合。图形元素可以是基本图形如圆形、矩形等,也可以是复杂的组合图形如图形群组。通过组合模式,我们可以以统一的方式处理单个图形元素和图形群组,从而实现图形的递归组合,构建出复杂的图形结构。

另一个例子是在操作系统文件系统中的应用。文件系统可以被组织成树形结构,目录可以包含子目录和文件。使用组合模式,我们可以统一处理目录和文件的操作,无需区分具体的文件和目录类型,从而简化了文件系统的操作。

需要注意的是,组合模式适用于对象组织结构稳定的情况。如果对象组织结构经常发生变化,可能导致频繁的节点增删操作,影响性能。在这种情况下,可以考虑使用其他设计模式来处理动态变化的情况。

总的来说,组合模式是一种强大的设计模式,能够有效地处理树形结构和部分整体层次结构,提高代码的灵活性和可维护性。在C++中,我们可以通过定义抽象组件类和具体组件类,以及创建叶子节点和组合节点来应用组合模式。通过组合模式,我们能够更加灵活地构建复杂的树形结构,实现了对象的递归组合,使得我们可以更好地处理复杂的对象组织关系。

希望本文能够帮助您深入理解组合模式的核心概念和用途,并通过C++的示例代码演示了如何应用组合模式来构建树形结构。在后续的专栏文章中,我们将继续介绍更多设计模式的知识,包括原理、详细介绍、示例代码和代码解析,帮助您深入学习和应用设计模式。

参考文献:

  • Gamma, E., Helm, R., Johnson, R., & Vlissides, J. (1994). Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley Professional.
  • C++ Core Guidelines: https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines

感谢您的阅读,欢迎一起探讨,共同进步,推荐大家使用学习助手AIRight来解答学习过程中的问题,访问链接:http://airight.fun/

相关文章:

篇九:组合模式:树形结构的力量

篇九&#xff1a;“组合模式&#xff1a;树形结构的力量” 开始本篇文章之前先推荐一个好用的学习工具&#xff0c;AIRIght&#xff0c;借助于AI助手工具&#xff0c;学习事半功倍。欢迎访问&#xff1a;http://airight.fun/。 另外有2本不错的关于设计模式的资料&#xff0c…...

【注册表】windows系统注册表常用修改方案

文章目录 ◆ 修改IE浏览器打印页面参数设置◆气泡屏幕保护◆彩带屏幕保护程序◆过滤IP(适用于WIN2000)◆禁止显示IE的地址栏◆禁止更改&#xff29;&#xff25;默认的检查(winnt适用)◆允许DHCP(winnt适用)◆局域网自动断开的时间(winnt适用)◆禁止使用“重置WEB设置”◆禁止更…...

ant-design-vue 4.x升级问题-样式丢失问题

[vue] ant-design-vue 4.x升级问题-样式丢失问题 项目环境问题场景解决方案 该文档是在升级ant-design-vue到4.x版本的时候遇到的问题 项目环境 "vue": "^3.3.4", "ant-design-vue": "^4.0.0", "vite": "^4.4.4&quo…...

【果树农药喷洒机器人】Part3:变量喷药系统工作原理介绍

本专栏介绍&#xff1a;免费专栏&#xff0c;持续更新机器人实战项目&#xff0c;欢迎各位订阅关注。 关注我&#xff0c;带你了解更多关于机器人、嵌入式、人工智能等方面的优质文章&#xff01; 文章目录 一、变量喷药系统工作原理二、液压通路设计与控制系统封装2.1液压通路…...

GoogLeNet创新点总结

GoogLeNet是一种深度卷积神经网络架构&#xff0c;于2014年由Google团队提出&#xff0c;是ILSVRC&#xff08;ImageNet Large Scale Visual Recognition Challenge&#xff09;比赛的冠军模型&#xff0c;其创新点主要集中在以下几个方面&#xff1a;   Inception模块&#…...

不同路径1、2、3合集(980. 不同路径 III)

不同路径一 矩形格&#xff0c;左上角 到 右下角。 class Solution {int [] directX new int[]{-1,1,0,0};int [] directY new int[]{0,0,-1,1};int rows;int cols;public int uniquePathsIII(int[][] grid) {if (grid null || grid.length 0 || grid[0].length 0) {ret…...

【云原生】Yaml文件详解

目录 一、YAML 语法格式1.1查看 api 资源版本标签1.2 写一个yaml文件demo1.3 详解k8s中的port 一、YAML 语法格式 Kubernetes 支持 YAML 和 JSON 格式管理资源对象JSON 格式&#xff1a;主要用于 api 接口之间消息的传递YAML格式&#xff1a;用于配置和管理&#xff0c;YAML 是…...

ffmpeg下载安装教程

ffmpeg官网下载地址https://ffmpeg.org/download.html 这里以windows为例,鼠标悬浮到windows图标上,再点击 Windows builds from gyan.dev 或者直接打开 https://www.gyan.dev/ffmpeg/builds/ 下载根据个人需要下载对应版本 解压下载的文件,并复制bin所在目录 新打开一个命令…...

uniapp之当你问起“tab方法触发时eventchange也跟着触发了咋办”时

我相信没有大佬会在这个问题上卡两个小时吧&#xff0c;记下来大家就当看个乐子了。 当时问题就是&#xff0c;点击tab头切换的时候&#xff0c;作为tab滑动事件的eventchange同时触发了&#xff0c;使得接口请求了两次 大概是没睡好&#xff0c;我当时脑子老想着怎么阻止它冒…...

TS 踩坑之路(四)之 Vue3

一、在使用定义默认值withDefaults和defineProps 组合时&#xff0c;默认值设置报错 代码案例 报错信息 不能将类型“{ isBackBtn: false; }”分配给类型“(props: PropsType) > RouteMsgType”。 对象字面量只能指定已知属性&#xff0c;并且“isBackBtn”不在类型“(pro…...

【音视频】edge与chrome在性能上的比较

目录 结论先说 实验 结论 实验机器的cpu配置 用EDGE拉九路​编辑 google拉五路就拉不出来了 资源使用情况 edge报错​编辑 如果服务器端 性能也满 了&#xff0c;就会不回复&#xff1b;验证方式 手动敲 8081&#xff0c;不回应。 结论先说 实验 用chrome先拉九路&#…...

Docker Compose编排部署LNMP服务

目录 安装docker-ce 阿里云镜像加速器 文件 启动 安装docker-ce [rootlocalhost ~]# wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo --2023-08-03 18:34:32-- http://mirrors.aliyun.com/repo/Centos-7.repo 正在解析主机 m…...

git使用(常见用法)

一.下载git git官方下载跳转 安装简单,有手就行 二. git的简单使用 1. 连接远程仓库 #初始化 git init #配置账户 git config --global user.name “输入你的用户名” git config --global user.email “输入你的邮箱” git config --list #--q退出 #配置验证邮箱 ssh-key…...

用例拆分情况考虑方案

文章目录 1、方案一方案概述方案分析(1) 把对应图商地图的逻辑给分离开(2) 要使用命令行的方式执行方法 2、方案二3、最终决定 1、方案一 方案概述 每个图商&#xff08;GD、BD、自建&#xff09;拆分成单独的类 把参数化的几个图商类别拆分成对应的图商类&#xff0c;在每个类…...

一文搞懂IS-IS报文通用格式

报文格式 IS-IS报文是直接封装在数据链路层的帧结构中的。PDU可以分为两个部分&#xff0c;报文头和变长字段部分。其中头部又可分为通用头部和专用头部。对于所有PDU来说&#xff0c;通用报头都是相同的&#xff0c;但专用报头根据PDU类型不同而有所差别。 IS-IS的PDU有4种类…...

位置参数 关键字参数

在Python中&#xff0c;函数参数可以按照位置或关键字来传递。这导致了两种主要的参数类型&#xff1a;位置参数和关键字参数。 位置参数: 这是最常见的参数类型&#xff0c;当我们调用函数时&#xff0c;传递给函数的参数值是按照它们的位置来确定的。例如&#xff0c;def fun…...

【果树农药喷洒机器人】Part5:基于深度相机与分割掩膜的果树冠层体积探测方法

文章目录 一、引言二、树冠体积测量对比方法2.1冠层体积人工测量法2.2冠层体积拟合测量法 三、基于深度相机与分割掩膜探测树冠体积方法3.1像素值与深度值的转换3.2树冠体积视觉探测法3.3实验分析 总结 一、引言 果树靶标探测是实现农药精准喷施的关键环节&#xff0c;本章以果…...

生活小妙招之UE custom Decal

因为这几年大部分时间都在搞美术&#xff0c;所以博客相关的可能会鸽的比较多&#xff0c;阿巴阿巴 https://twitter.com/Tuatara_Games/status/1674034744084905986 之前正好看到一个贴花相关的小技巧&#xff0c;正好做一个记录&#xff0c;也在这个的基础上做一些小的拓展…...

DAY02_Spring—第三方资源配置管理Spring容器Spring注解开发Spring整合Mybatis和Junit

目录 一 第三方资源配置管理1 管理DataSource连接池对象问题导入1.1 管理Druid连接池1.2 管理c3p0连接池 2 加载properties属性文件问题导入2.1 基本用法2.2 配置不加载系统属性2.3 加载properties文件写法 二 Spring容器1 Spring核心容器介绍问题导入1.1 创建容器1.2 获取bean…...

Icon图标有哪些在线设计的工具推荐

虽然icon图标相对较小&#xff0c;但icon图标在设计中非常重要。高质量的icon图标通常可以决定设计工作的质量。高质量的在线生产icon工具可以提高设计师图标设计的效率。此外&#xff0c;优秀的图标设计师还可以让设计师快速开始图标设计工作。本文为您选择了五种在线生成icon…...

OpenLayers 可视化之热力图

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 热力图&#xff08;Heatmap&#xff09;又叫热点图&#xff0c;是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 &#xff08;一&#xff09;实时滤波与参数调整 基础滤波操作 60Hz 工频滤波&#xff1a;勾选界面右侧 “60Hz” 复选框&#xff0c;可有效抑制电网干扰&#xff08;适用于北美地区&#xff0c;欧洲用户可调整为 50Hz&#xff09;。 平滑处理&…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂

蛋白质结合剂&#xff08;如抗体、抑制肽&#xff09;在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上&#xff0c;高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术&#xff0c;但这类方法普遍面临资源消耗巨大、研发周期冗长…...

STM32+rt-thread判断是否联网

一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具&#xff0c;可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下&#xff1a; ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜&#xff1a; ffmpeg…...

Qt Http Server模块功能及架构

Qt Http Server 是 Qt 6.0 中引入的一个新模块&#xff0c;它提供了一个轻量级的 HTTP 服务器实现&#xff0c;主要用于构建基于 HTTP 的应用程序和服务。 功能介绍&#xff1a; 主要功能 HTTP服务器功能&#xff1a; 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

【决胜公务员考试】求职OMG——见面课测验1

2025最新版&#xff01;&#xff01;&#xff01;6.8截至答题&#xff0c;大家注意呀&#xff01; 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:&#xff08; B &#xff09; A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

MySQL用户和授权

开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务&#xff1a; test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...

Element Plus 表单(el-form)中关于正整数输入的校验规则

目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入&#xff08;联动&#xff09;2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...