组合模式(Composite)
组合模式是一种结构型设计模式,主要用来将多个对象组织成树形结构以表示“部分-整体”的层次结构,因此该模式也称为“部分-整体”模式。简言之,组合模式就是用来将一组对象组合成树状结构,并且能像使用独立对象一样使用它们。
Composite is a structural design pattern that lets you organize multiple objects into a tree structure to represent the "part whole" relationship. In short, the composite pattern can be used to combine a group of objects into a tree structure and use them as independent objects.
结构设计
为实现组合模式,首先需要创建一个可以组合多个对象的单一对象(Component),这个对象用来访问和管理其子对象,并对外提供公共接口。然后,定义没有子节点的对象(Leaf,基本对象)和包含子对象的对象(Composite,组合对象)。最后,将这些对象组装到之前创建的对象上。这样,外部(Client)就可通过Component调用公共接口。组合模式包含如下角色:
Component,组合对象,为组合中的对象声明公共接口,并提供默认实现。
Leaf,叶节点对象,叶节点最终会完成大部分的实际工作,因为它们无法将工作指派给其他部分。
Compoiste,组合,也称容器,包含叶节点或其他容器的单位。容器不知道其子项目所属的具体类, 它只通过通用的组件接口与其子项目交互。
组合模式类图表示如下:

注意:
(1) 组合模式对基本对象和组合对象的使用具有一致性。外部代码调用Component公共接口时,无需区别对待基本对象和组合对象(透明性),大多数情况下可以一致地处理它们。
伪代码实现
接下来将使用代码介绍下组合模式的实现。
// 1、Component,组合对象,为组合中的对象声明公共接口,并提供默认实现。
public abstract class Component {private String name;protected List<Component> children = new ArrayList<>();public Component(String componentName) {this.name = componentName;}public void operation() {System.out.println(this.name);}public Component getChild(String componentName) {for (Component current : children) {if (current.name.equals(componentName)) {return current;}Component childComponent = current.getChild(componentName);if (childComponent != null) {return childComponent;}}return null;}public abstract void add(Component component);public abstract void remove(Component component);
}
// 2、Compoiste,组合,也称容器,包含叶节点或其他容器的单位。容器不知道其子项目所属的具体类,
// 它只通过通用的组件接口与其子项目交互。
public class Composite extends Component {public Composite(String componentName) {super(componentName);}@Overridepublic void add(Component component) {this.children.add(component);}@Overridepublic void remove(Component component) {this.children.remove(component);}
}
// 3、Leaf,叶节点对象,叶节点最终会完成大部分的实际工作,因为它们无法将工作指派给其他部分。
public class Leaf extends Component {public Leaf(String componentName) {super(componentName);}@Overridepublic void add(Component component) {throw new RuntimeException("叶节点不能添加子节点");}@Overridepublic void remove(Component component) {throw new RuntimeException("叶节点不包含子节点,无法移除子节点");}
}
// 4、客户端调用
public class CompositeClient {public void test() {Component root = new Composite("root");root.add(new Leaf("Leaf A"));Composite branch = new Composite("Composite X");Leaf leafXa = new Leaf("Leaf XA");branch.add(leafXa);branch.add(new Leaf("Leaf XB"));branch.remove(leafXa);root.add(branch);Component leafXb = root.getChild("Leaf XB");leafXb.operation();}
}
这里只介绍了基于透明性的设计与实现,组合模式还支持一种基于安全性的设计与实现,更多安全性相关知识可以执行搜索并学习。
适用场景
在以下情况下可以考虑使用组合模式:
(1) 如果需要实现树状对象结构, 可以考虑使用组合模式。
组合模式提供了两种共享公共接口的基本元素类型:简单叶节点和复杂容器。容器中可以包含叶节点和其他容器。这使得开发者可以构建树状嵌套递归对象结构。
(2) 如果希望客户端代码以相同方式处理简单和复杂元素, 可以使用该模式。
组合模式中定义的所有元素共用同一个接口。在这一接口的帮助下,客户端不必在意其所使用的对象的具体类。
优缺点
组合模式最大特点是将多个对象组织成树形结构。组合模式有以下优点:
(1) 可以利用多态和递归机制更方便地使用复杂树结构。
(2) 符合开闭原则。无需更改现有代码,开发者就可以在应用中添加新元素,使其成为对象树的一部分。
但是组合模式也存在以下缺点:
(1) 对于功能差异较大的类, 提供公共接口或许会有困难。在特定情况下,开发者需要过度一般化组件接口,使其变得令人难以理解。
参考
《设计模式:可复用面向对象软件的基础》 Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides 著 李英军, 马晓星 等译
https://refactoringguru.cn/design-patterns/composite 组合模式
https://www.cnblogs.com/adamjwh/p/9033547.html 简说设计模式——组合模式
https://blog.csdn.net/ShuSheng0007/article/details/116378002 秒懂设计模式之组合模式(Composite Pattern)
https://www.runoob.com/design-pattern/composite-pattern.html 组合模式
相关文章:
组合模式(Composite)
组合模式是一种结构型设计模式,主要用来将多个对象组织成树形结构以表示“部分-整体”的层次结构,因此该模式也称为“部分-整体”模式。简言之,组合模式就是用来将一组对象组合成树状结构,并且能像使用独立对象一样使用它们。 Co…...
grid map学习笔记3之详解grid_map_pcl库实现point cloud点云转换成grid map栅格地图
文章目录 0 引言1 grid_map_pcl示例1.1 主要文件1.2 示例数据1.3 启动文件1.4 配置文件1.5 主要实现流程1.6 启动示例1.7 示例结果 2 D435i 点云生成栅格地图2.1 D435i 点云文件2.2 修改启动文件2.3 测试和结果2.4 修改配置文件2.5 重新测试和结果 0 引言 grid map学习笔记1已…...
ebpf开发问题汇总
不同Programs之间通信 用bpf_obj_get来获取MAP的描述符,然后用bpf_map_reuse_fd函数来在不同program之间复用 kernel 与 user space之间 需要pin the BPF MAP to the BPF Virtual File System (VFS),来持久化存储,否则如果map用不到会被destory 引用…...
认识 mysql 命令
文章目录 1.简介2.选项3.子命令4.小结参考文献 1.简介 mysql 是 MySQL 的命令行客户端工具,用于连接到 MySQL 服务器并执行 SQL 语句。 它支持交互式和非交互式两种使用方式。以交互方式使用时,查询结果以 ASCII 表格式呈现。 当以非交互方式使用时&am…...
IK(Inverse Kinematics,逆运动学)
介绍 在Unity中,IK(Inverse Kinematics,逆运动学)是一种用于控制角色或物体骨骼的技术。通过使用IK,可以实现更自然和真实的动画效果,特别是在处理复杂的角色动作时非常有用。 IK Pass是Unity中的一个功能…...
Cadence 小技巧系列(持续更新)
■ ADE setup simulator/directory/host 更改仿真路径,默认home路径空间太小了,改成当前路径就行。 瞬态tran仿真要用APS跑(setup--high...) 瞬态tran仿真精度设置,conservation,option--maxstep设为0.1n…...
【unity】Pico VR 开发笔记(基础篇)
Pico VR 开发笔记(基础篇) XR Interaction Tooikit 版本 2.3.2 一、环境搭建 其实官方文档已经写的很详细了,这里只是不废话快速搭建,另外有一项官方说明有误的,补充说明一下,在开发工具部分说明 插件安装——安装pico的sdk和XR…...
竞争之王CEO商战课,聚百家企业在京举行
竞争之王CEO商战课,于2023年7月29-31日在北京临空皇冠假日酒店举办,近百家位企业家齐聚一堂,共享饕餮盛宴。 竞争之王CEO商战课是打赢商战的第一课。 竞争环境不是匀速变化,而是加速变化。 在未来的市场环境中,企业间…...
【shell】获取ping的时延数据并分析网络情况及常用命令学习
文章目录 获取ping的时延数据并分析网络情况|、||、&、&&辨析teetailkillall 获取ping的时延数据并分析网络情况 网络情况经常让我们头疼,每次都需要手动在终端ping太麻烦了,不如写个脚本ping并将数据带上时间戳存入文件,然后也…...
石子合并一章通(环形石子合并,四边形不等式,GarsiaWachs算法)(内附封面)
[NOI1995] 石子合并 题目描述 在一个圆形操场的四周摆放 N N N 堆石子,现要将石子有次序地合并成一堆,规定每次只能选相邻的 2 2 2 堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分。 试设计出一个算法,计算出将 …...
Docker快速入门笔记
Docker快速入门 前言 当今软件开发领域的一股热潮正在迅速兴起,它融合了便捷性、灵活性和可移植性,让开发者们欣喜若狂。它就是 Docker!无论你是一个初学者,还是一位经验丰富的开发者,都不能错过这个引领技术浪潮的工…...
【Excel】记录Match和Index函数的用法
最近一直用到的两个处理EXCEL表格数据的函数向大家介绍一下,写这篇博文的目的也是为了记录免得自己忘记了,嘻嘻。 先上百度的链接 Match函数的用法介绍:https://jingyan.baidu.com/article/2fb0ba40b4933941f3ec5f71.html 小结:…...
SolidUI社区-从开源社区角度思考苹果下架多款ChatGPT应用
文章目录 背景下架背景下架原因趋势SolidUI社区的未来规划结语如果成为贡献者 背景 随着文本生成图像的语言模型兴起,SolidUI想帮人们快速构建可视化工具,可视化内容包括2D,3D,3D场景,从而快速构三维数据演示场景。SolidUI 是一个创新的项目…...
插入排序讲解
插入排序(Insertion-Sort)一般也被称为直接插入排序。对于少量元素的排序,它是一个有效的算法。插入排序是一种最简单的排序方法,它的基本思想是将一个记录插入到已经排好序的有序表中,从而一个新的、记录数增1的有序表…...
杀疯了的ChatGPT——开启AI智能交流新纪元 「文末有彩蛋」
欢迎打开 ChatGPT 的新世纪大门 🌍 目录 😊 引言😎 ChatGPT 的高级之处1. 巨大的模型规模2. 广泛的知识覆盖3. 零样本学习4. 多语言支持5. 上下文感知对话 🤖 如何使用 ChatGPT1. 智能助手2. 个性化交互3. 语言学习伙伴4. 创造性写…...
web爬虫第五弹 - JS逆向入门(猿人学第一题)
0- 前言 爬虫是一门需要实战的学问。 而对于初学者来说,要想学好反爬,js逆向则是敲门砖。今天给大家带来一个js逆向入门实例,接下来我们一步一步来感受下入门的逆向是什么样的。该案例选自猿人学练习题。猿人学第一题 1- 拿到需求 进入页面…...
P5731 【深基5.习6】蛇形方阵
题目描述 给出一个不大于 9 9 9 的正整数 n n n,输出 n n n\times n nn 的蛇形方阵。 从左上角填上 1 1 1 开始,顺时针方向依次填入数字,如同样例所示。注意每个数字有都会占用 3 3 3 个字符,前面使用空格补齐。 输入格式…...
Python实现GA遗传算法优化循环神经网络回归模型(LSTM回归算法)项目实战
说明:这是一个机器学习实战项目(附带数据代码文档视频讲解),如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 遗传算法(Genetic Algorithm,GA)最早是由美国的 John holland于20世…...
ESD防静电监控系统在SMT产线中的应用案例
作为电子厂的关键制造环节之一,SMT(表面贴装技术)产线的效率和质量对企业的竞争力至关重要。为了提高生产线的管理效率和保障生产环境的质量,许多电子厂开始采用MES生产管理系统和ESD防静电监控系统的综合解决方案。 在SMT产线中安…...
Vue+Nodejs+Express+Minio 实现本地图片上传
安装Minio,Minio server和Minio client都要下载可以自定义安装目录 安装完成之后,可以将minio配置成环境变量方便使用 配置了环境变量启动命令式 minio server start,默认账号密码minioadmin和minioadmin,点击9000端口的这个链接,即可访问客户端 nodejs连接Minio,简易服务进…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...
springboot整合VUE之在线教育管理系统简介
可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生,小白用户,想学习知识的 有点基础,想要通过项…...
Java编程之桥接模式
定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...
Unity UGUI Button事件流程
场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...
深入浅出Diffusion模型:从原理到实践的全方位教程
I. 引言:生成式AI的黎明 – Diffusion模型是什么? 近年来,生成式人工智能(Generative AI)领域取得了爆炸性的进展,模型能够根据简单的文本提示创作出逼真的图像、连贯的文本,乃至更多令人惊叹的…...
k8s从入门到放弃之HPA控制器
k8s从入门到放弃之HPA控制器 Kubernetes中的Horizontal Pod Autoscaler (HPA)控制器是一种用于自动扩展部署、副本集或复制控制器中Pod数量的机制。它可以根据观察到的CPU利用率(或其他自定义指标)来调整这些对象的规模,从而帮助应用程序在负…...
解析两阶段提交与三阶段提交的核心差异及MySQL实现方案
引言 在分布式系统的事务处理中,如何保障跨节点数据操作的一致性始终是核心挑战。经典的两阶段提交协议(2PC)通过准备阶段与提交阶段的协调机制,以同步决策模式确保事务原子性。其改进版本三阶段提交协议(3PC…...
