C++设计模式——Composite组合模式
一,组合模式简介
真实世界中,像企业组织、文档、图形软件界面等案例,它们在结构上都是分层次的。将系统分层次的方式使得统一管理和添加不同子模块变得容易,在软件开发中,组合模式的设计思想和它们类似。
组合模式是一种结构型设计模式,该模式将对象组合成树状结构,以便于分层和统一管理。
组合模式用于为复杂的分层的系统结构定义基本的蓝图,并对外提供统一的接口,简化了系统组件的使用方法。
二,组合模式的结构
1.组件类(Component):声明了统一的抽象接口。它定义了Leaf类和Composite类的通用函数接口。
2.叶子节点类(Leaf):提供了Component类的接口实现,组合模式中的最小单元。
3.组合类(Composite):也提供了Component类的接口实现,其中包含多个Component对象。它对子组件进行了封装,使用客户端(Client)可以像操作单个组件一样使用整个组合。
对应UML类图:
三,组合模式代码样例
Demo1:先操作叶子节点,后操作主节点
#include <iostream>
#include <vector>class Component {
public:virtual void operation() const = 0;virtual ~Component() {}
};class Leaf : public Component {
public:Leaf(const std::string& name) : name_(name) {}virtual void operation() const override {std::cout << "Operation on leaf: " << name_ << std::endl;}
private:std::string name_;
};class Composite : public Component {
public:Composite(const std::string& name) : name_(name), children_{} {}void add(Component* component) {children_.push_back(component);}void operation() const override {for (const auto& child : children_) {child->operation();}std::cout << "Operation on composite: " << name_ << std::endl;}
private:std::vector<Component*> children_;std::string name_;
};int main() {Composite root("Composite Root");Leaf leaf1("Leaf 1");Leaf leaf2("Leaf 2");Leaf leaf3("Leaf 3");root.add(&leaf1);root.add(&leaf2);root.add(&leaf3);root.operation();return 0;
}
运行结果:
Operation on leaf: Leaf 1
Operation on leaf: Leaf 2
Operation on leaf: Leaf 3
Operation on composite: Composite Root
Demo2:先操作主节点,后操作叶子节点
#include <iostream>
#include <vector>class Component {
public:virtual ~Component() {}virtual void operation() const = 0;
};class Leaf : public Component {
public:Leaf(const std::string& name) : name(name) {}virtual void operation() const override {std::cout << "Operation on leaf: " << name << '\n';}
private:std::string name;
};class Composite : public Component {
public:Composite(const std::string& name) : Component(), children(), _name(name) {}void add(Component* component) {children.push_back(component);}void remove(Component* component) {children.erase(std::remove(children.begin(),children.end(),component),children.end());}void operation() const override {std::cout << "Operation on composite: " << _name << '\n';for (auto& child : children)child->operation();}private:std::vector<Component*> children;std::string _name;
};int main() {Composite root("Composite1");root.add(new Leaf("Leaf1"));root.add(new Leaf("Leaf2"));root.add(new Composite("Composite2"));root.add(new Leaf("Leaf3"));root.operation();return 0;
}
运行结果:
Operation on composite: Composite1
Operation on leaf: Leaf1
Operation on leaf: Leaf2
Operation on composite: Composite2
Operation on leaf: Leaf3
四,组合模式的应用场景
平面设计软件开发:在Photoshop等应用程序中,形状、线条和文本等图形元素可以组合成复杂的设计。
文件系统:使用组合模式来表示文件和目录,从而形成可以统一处理和查询的分层结构。
UI框架开发:基于组合模式,可以让UI组件(如按钮、标签和面板等)组合成复杂的布局或界面。
文档编辑器:使用组合模式来实现文档的段落和文本等层次结构。
企业软件开发:企业软件通常对组织结构进行建模,包括部门、团队和员工。组合模式用于实现组织单位及其内部员工的层次结构。
五,组合模式的优缺点
组合模式的优点:
1.便于维护和重构,修改单个组件的代码不会影响整个系统的功能。
2.有树形结构的先天优势,可以很方便地统一添加、删除或修改子节点。
3.通过拆分子组件,提高了模块间的独立性和可重用性。
4.符合"单一职责原则",组合中的每个对象只关注自己的职责,不需要考虑整个组合中的功能配合。
组合模式的缺点:
1.性能开销大,该模式涉及了对象的动态创建和管理,频繁操作可能会引起性能问题。
2.增加了代码的复杂度,当组合的层次过深的时候,代码的结构会很复杂。
3.类型安全问题,当管理多个组件对象时,可能需要额外的类型转换编码。
六,代码实战
代码实战:基于组合模式实现的文件系统
#include <iostream>
#include <bits/stdc++.h>class FileSystemComponent {
public:virtual void display() const = 0;
};class File : public FileSystemComponent {
public:File(const std::string& name, int size): name(name), size(size){}void display() const override{std::cout << "File: " << name <<" (" << size << " bytes)" <<std::endl;}
private:std::string name;int size;
};class Directory : public FileSystemComponent {
public:Directory(const std::string& name): name(name){}void display() const override{std::cout << "Directory: " << name << std::endl;for (const auto& component : components) {component->display();}}void addComponent(FileSystemComponent* component){components.push_back(component);}
private:std::string name;std::vector<FileSystemComponent*> components;
};int main()
{FileSystemComponent* file1= new File("document.txt", 1024);FileSystemComponent* file2= new File("image.jpg", 2048);Directory* directory = new Directory("My Documents");directory->addComponent(file1);directory->addComponent(file2);directory->display();return 0;
}
运行结果:
Directory: My Documents
File: document.txt (1024 bytes)
File: image.jpg (2048 bytes)
七,参考阅读
相关文章:
![](https://img-blog.csdnimg.cn/direct/07f9321607de46e689034d23d5f04219.png)
C++设计模式——Composite组合模式
一,组合模式简介 真实世界中,像企业组织、文档、图形软件界面等案例,它们在结构上都是分层次的。将系统分层次的方式使得统一管理和添加不同子模块变得容易,在软件开发中,组合模式的设计思想和它们类似。 组合模式是…...
![](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=https%3A%2F%2Fimg2.imgtp.com%2F2024%2F05%2F27%2FecnWy72K.jpg&pos_id=img-7R2o989d-1718991877996)
Android提供的LruCache类简介(1)
* If your cached values hold resources that need to be explicitly released, * override {link #entryRemoved}. * 如果你cache的某个值需要明确释放,重写entryRemoved() * If a cache miss should be computed on demand for the corresponding keys, * ov…...
![](https://img-blog.csdnimg.cn/img_convert/a08571f736dc04b5bef51cd09e8e3a0a.gif#pic_center)
【分布式系列】分布式锁timeout了怎么办?
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...
![](https://www.ngui.cc/images/no-images.jpg)
System.getProperty()方法总结
System.getProperty()方法总结 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!System.getProperty()方法是Java中用于获取系统属性的方法之一。它允许我们访问J…...
![](https://img-blog.csdnimg.cn/direct/d7b0ecab0c5b4ae79cbc57783bdbbaf5.png)
大型语言模型在AMD GPU上的推理优化
Large language model inference optimizations on AMD GPUs — ROCm Blogs 大型语言模型(LLMs)已经改变了自然语言处理和理解,促进了在多个领域中的众多人工智能应用。LLMs在包括AI助手、聊天机器人、编程、游戏、学习、搜索和推荐系统在内的…...
![](https://img-blog.csdnimg.cn/direct/ad11123a13d94985a63b9be75f0a328e.png)
Apple - Core Foundation Design Concepts
本文翻译整理自:Core Foundation Design Concepts(更新日期:2013-12-16 https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFDesignConcepts/CFDesignConcepts.html#//apple_ref/doc/uid/10000122i 文章…...
![](https://www.ngui.cc/images/no-images.jpg)
lua中的lfs库介绍
lua中的lfs库介绍 说明常用函数解析lfs.attributeslfs.chdirlfs.currentdirlfs.dirlfs.mkdirlfs.rmdirlfs.locklfs.touchlfs.linklfs.setmodelfs.symlinkattributes 说明 lfs是lua中的一个文件系统库,提供了更多高级的文件和目录操作功能,使得lua可以更方…...
![](https://www.ngui.cc/images/no-images.jpg)
PyCharm 快捷键积累
1、快速格式化:Ctrl Alt L Ctrl Alt L 快捷键在 PyCharm 中是用于格式化代码的,它不仅仅适用于 HTML 代码,而是适用于多种编程和标记语言。...
![](https://img-blog.csdnimg.cn/direct/1364ead010e7498c893ddedb8419b3c8.png)
C++进阶之AVL树
个人主页:点我进入主页 专栏分类:C语言初阶 C语言进阶 数据结构初阶 Linux C初阶 C进阶 算法 欢迎大家点赞,评论,收藏。 一起努力,一起奔赴大厂 目录 一.前言 二.插入 三.旋转 3.1右旋 …...
![](https://www.ngui.cc/images/no-images.jpg)
sizeof 和 strlen 比较
sizeof 和 strlen 在 C 语言中都是用于获取某种“大小”的,但它们之间有着显著的区别。 sizeof sizeof 是一个运算符,用于计算数据类型或对象在内存中的大小(以字节为单位)。它可以在编译时确定结果,因为它计算的是类…...
![](https://img-blog.csdnimg.cn/direct/e07711ff5a17448c8e2518a38ef33677.png#pic_center)
音视频开发—FFmpeg 打开摄像头进行RTMP推流
实验平台:Ubuntu20.04 摄像头:普通USB摄像头,输出格式为YUV422 1.配置RTMP服务器推流平台 使用Nginx 配置1935端口即可,贴上教程地址 ubuntu20.04搭建Nginxrtmp服务器) 2.配置FFmpeg开发环境 过程较为简单,这里不…...
![](https://img-blog.csdnimg.cn/direct/618336344a324d39b6501b3973f5fc4b.png)
D触发器(D Flip-Flop)与D锁存器(D Latch)
1 基础概念 我们先来简单回顾一下D触发器(D flip-flop)和D锁存器(D latch)的概念,以及它们在数字电路中的作用。 1.1 D触发器(D Flip-Flop) D触发器是一种数字存储器件,它在时钟信号…...
![](https://img-blog.csdnimg.cn/img_convert/e6bbb7110cb2431fdfec0c410e41cdc4.png)
JDK19特性
JDK19特性 一、JAVA19概述 JDK 19 2022 年 9 月 20 日正式发布以供生产使用,非长期支持版本。不过,JDK 19 中有一些比较重要的新特性值得关注。 JDK 19 只有 7 个新特性: JEP 405: Record Patterns(记录模式)[1] (预览)JEP 422: Linux/RISC-V Port[2]JEP 424: Foreign …...
![](https://www.ngui.cc/images/no-images.jpg)
sql语句中常用的函数有那些
1、字符串函数 CONCAT(string1, string2, ...): 连接两个或多个字符串。 UPPER(string): 将字符串转换为大写。 LOWER(string): 将字符串转换为小写。 TRIM(string): 去除字符串两端的空格。 LENGTH(string): 返回字符串的长度。 SUBSTRING(string, start, length): 从字符串中…...
![](https://www.ngui.cc/images/no-images.jpg)
odoo17 小变更3 Warning、 “attrs “和 “states “不再用
odoo17 小变更 1、Warning from odoo.exceptions import ValidationError,Warning ImportError: cannot import name Warning from odoo.exceptions (D:\od172406\odoo\exceptions.py) 2、自 17.0 版起,不再使用 "attrs "和 "states "属性。 …...
![](https://img-blog.csdnimg.cn/direct/7bf6f89b86b044b1aa8b801d519ab4a2.gif#pic_center)
Unity3d 游戏暂停(timeScale=0)引起的deltaTime关联的系列问题解决
问题描述 游戏暂停的功能是通过设置timeScale0实现的,不过在暂停游戏的时候,需要对角色进行预览和设置,为了实现这个功能,是通过鼠标控制相机的操作,为了使相机的操作丝滑,获取鼠标操作系数乘以Time.delta…...
![](https://img-blog.csdnimg.cn/direct/1a6438e9ebd249f0a07362050688007c.png)
服务端代码编写中MySql大小写在Java中报错问题解决
报错信息: 原因:MySql和Java变量大小写产生的冲突。 经过查阅各个博客等,得出浅显结论(不一定对):MySql大小写不敏感,Java大小写敏感,当Javabean转为MySql数据库表时,Ja…...
![](https://img-blog.csdnimg.cn/img_convert/13fd3f8cd570b9273e80d8e097729697.png)
CRMEB 多店商品详情页装修说明
一、功能介绍 商家可调整商品详情各板块样式,可根据不同的需求开启或关闭单独的板块 二、操作流程 装修 > 商品详情 三、功能说明 1、商品信息 可控制商品详情页面商品信息的显示与隐藏 2、会员信息,排行榜 控制商品详情页面会员信息及排行榜的…...
![](https://img-blog.csdnimg.cn/direct/478c34bc25044146b83472c15e03565f.png)
Redis-使用 jedis 操作数据
文章目录 1、Jedis简介2、环境准备3、创建maven普通项目,导入如下依赖4、测试JAVA程序和Redis之间的通信 1、Jedis简介 "Jedis" 通常是作为 "Java Redis" 的缩写或简称来理解的。Java Embedded Data Structures Interface 表示 Java嵌入式数据结构接口 2、…...
![](https://www.ngui.cc/images/no-images.jpg)
简说PIP换源
概述 PIP(Python Package Installer)是 Python 的包管理工具,用于安装和管理 Python 包。默认情况下,PIP 从 Python 官方的包仓库(即 PyPI)下载和安装包。然而,由于网络原因,访问官…...
![](https://img-blog.csdnimg.cn/direct/601a534271964e33ad9aa71ef7e73581.png)
django学习入门系列之第三点《CSS基础样式介绍2》
文章目录 文字对齐方式外边距内边距往期回顾 文字对齐方式 水平对齐方式 text-align: center;垂直对齐方式 /* 注意,这个只能是一行来居中 */ line-height:/*长度*/ ;样例 <!DOCTYPE html> <html lang"en"> <head><meta charset…...
![](https://img-blog.csdnimg.cn/direct/e90cd99b1e7b4867857e87b567274b0c.png#pic_center)
分布式光纤测温DTS在工程现场中稳定性与可靠性如何?
20年前,分布式光纤测温(Distributed Temperature Sensing,DTS)技术的发展尚不成熟,设备成本高昂,其稳定性与可靠性也存在一定问题。然而,经过二十多年的不断发展与创新,DTS技术在工程现场应用中取得了显著进…...
![](https://www.ngui.cc/images/no-images.jpg)
PHP多线程模块parallel的编译安装和多线程编程演示
从PHP7开始,多线程编原有的pthreads已经不在维护,而是使用parallel替代。 由于是新的模块,样例代码很少,这里总结一个简单的代码和详细的备注供大家参考。 编译和安装 parallel需要启用ZTS(Zend Thread Safety&…...
![](https://www.ngui.cc/images/no-images.jpg)
记录grid布局属性
grid布局 分为容器和项目元素 容器属性 #container{display:grid;grid-template-columns:100px 100px 100px;/* 1fr 表示比例为占1份 */grid-template-columns:1fr 100px 1fr;/*100px为1列,自动填充,容器宽度不足则换行*/grid-template-columns:repeat(auto-fill,100px);/* …...
![](https://img-blog.csdnimg.cn/direct/d38c1e644f384e22adf522b971abeefe.png#pic_center)
12.爬虫---PyMysql安装与使用
12.PyMysql安装与使用 1.安装 PyMySQL2.使用PyMySQL2.1创建数据表2.2连接数据库2.3增加数据2.4修改数据2.5查询数据2.6删除数据2.7关闭连接 3.总结 MySQL 安装可以看这篇文章MySql 安装与使用(非常详细) 1.安装 PyMySQL PyMySQL是Python中用于连接MySQL…...
![](https://img-blog.csdnimg.cn/direct/5d09350d03454ad7a1a851bdcb31d392.png)
VS2022遇到的两个问题
问题一:找不到定义的头文件 别的博主说是:在属性页里面进行改写,改成是,我试过之后并不行; 解决思路:但其实在右边视图里面找到你自己定义的头文件加到你运行文件中就行;因为程序就只有一个入口…...
![](https://img-blog.csdnimg.cn/direct/3deca5334eca4871aecce8beff21bcc2.png)
【Android14 ShellTransitions】(六)SyncGroup完成
这一节的内容在WMCore中,回想我们的场景,是在Launcher启动某一个App,那么参与动画的就是该App对应Task(OPEN),以及Launcher App对应的Task(TO_BACK)。在确定了动画的参与者后&#x…...
![](https://img-blog.csdnimg.cn/direct/ddc4532122ea4c86beab62ea2dc5b501.jpeg#pic_center)
技术管理转型之战:决策之道-管理中的智慧与策略
文章目录 引言一、决策的重要性二、常见的决策方式1. 理性决策(Rational Decision Making)2. 有限理性(Bounded Rationality)3. 直觉决策(Intuitive Decision Making)4. 循证管理(Evidence-Base…...
![](https://img-blog.csdnimg.cn/direct/20a0213880ed49939c01a9890e559f38.png)
Shell脚本:条件语句(if、case)
目录 硬编码 硬编码的缺点 条件判断 $? 命令行语句 判断指定目录是否存在 判断指定文件是否存在 判断指定对象是否存在 表达式形式语句 判断对象是否存在 判断对象是否有权限 与、或、非 运算 与运算 或运算 非运算 比较大小 判断磁盘利用率实验步骤 字符串…...
![](https://www.ngui.cc/images/no-images.jpg)
在Linux上为Windows目标配置Qt交叉编译
问题描述 我想使用Linux x86_64主机为Windows x86_64目标交叉编译Qt库(最终也包括我的应用程序)。我觉得自己已经接近成功了,但可能对整个过程有一些基本的误解。 我从在我的Fedora机器上安装所有mingw包开始,并修改了win32-g的…...
![](/images/no-images.jpg)
网站开发主要框架 后端/网站优化推广教程
摘要:本文所讲述的内容,为ElasticSearch(以下简称ES)全文搜索引擎在实际大数据项目的应用;ES的底层是开源库 Lucene。但是,你没法直接用 Lucene,必须自己写代码去调用它的接口。ES 是 Lucene 的…...
![](/images/no-images.jpg)
php网站建设制作设计/优秀网站
STL 基础引入—迭代器一,pair双元组1,构造2,提取值二,map(内部有序)三、nth_element四,set(有序平衡树)引入—迭代器 1,.end()返回的不是最后一个元素的位置…...
![](/images/no-images.jpg)
宝鸡做网站的/网站关键词查询
// //TITLE: // 预编译指令与相关宏小结 //AUTHOR: // norains //DATE: // Saturday 10-December-2007 //Environment: // EVC4.0 Windows CE 5.0 Standard SDK // 1.预编译指令 01) # 空指令,无任何效果 02) #include 包含一个源代码文件 03) #define 定义宏 04) …...
![](https://img-blog.csdnimg.cn/20200709170227163.png)
苏宁易购网站建设的思路/最近三天的新闻大事摘抄
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p 、q ,最近公共祖先表示为一个结点 x ,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己…...
建设网站需要什么资料/天津网络广告公司
解不等式: m1 < 1/2 √2/3 ... √n/(n1) < m2 算法分析: 这里正整数的m1和m2从键盘输入 设和s和递增变量index的初始值为0。 在s < m1的循环中,根据递增变量index对s累加求和,直至出现s > m1,退出循环,确定n的…...
![](/images/no-images.jpg)
网站建设推广营销策划/免费的app推广平台
原文链接:https://blog.csdn.net/forezp/article/details/80098675 本系列教程翻译于docker文档,文档地址:https://docs.docker.com/ ,由于某些原因,docker官方文档通常都是打不开,如果打不开,安装完docker…...