Java设计模式:结构型模式→组合模式
Java 组合模式详解
1. 定义
组合模式(Composite Pattern)是一种结构型设计模式,它允许将对象组合成树形结构以表示“部分-整体”的层次。组合模式使得客户端能够以统一的方式对待单个对象和对象集合的一致性,有助于处理树形结构中双重角色的复杂性。
2. 基本思想
组合模式的基本思想在于通过一个统一的接口将所有的组件(即单个对象和组合对象)抽象为一种接口,这样在执行操作时,客户端就无需关心组件是单个对象还是组合对象。组合模式在设计时遵循了“合成复用原则”,可以通过简化操作和封装复杂性来提高代码的灵活性和可扩展性。
3. 基本原理
组合模式主要由以下部分构成:
- 组件接口(Component):定义了树形结构中所有对象的接口,包括叶子节点(单个对象)和树枝节点(组合对象)的方法。
- 叶子节点(Leaf):实现组件接口的具体类,表示树结构中的基本元素,不能包含子节点。
- 树枝节点(Composite):同样实现组件接口,属于容器类型的对象,可以包含叶子节点或其他树枝节点。

更多实用资源:
http://sj.ysok.net/jydoraemon 访问码:JYAM
4. 实现方式
4.1 基本实现
4.1.1 组件接口
定义一个组件接口,描述基本的操作:
public interface Component {void operation();
}
4.1.2 叶子节点类
实现叶子节点,表示树的基本元素:
public class Leaf implements Component {private String name;public Leaf(String name) {this.name = name;}@Overridepublic void operation() {System.out.println("Leaf: " + name);}
}
4.1.3 树枝节点类
实现树枝节点,能够包含叶子和其他树枝:
import java.util.ArrayList;
import java.util.List;public class Composite implements Component {private List<Component> children = new ArrayList<>();private String name;public Composite(String name) {this.name = name;}public void add(Component component) {children.add(component);}public void remove(Component component) {children.remove(component);}@Overridepublic void operation() {System.out.println("Composite: " + name);for (Component child : children) {child.operation();}}
}
4.1.4 客户端代码
下面是客户端代码,展示如何使用组合模式:
public class Client {public static void main(String[] args) {Composite root = new Composite("Root");Leaf leaf1 = new Leaf("Leaf 1");Leaf leaf2 = new Leaf("Leaf 2");Composite composite1 = new Composite("Composite 1");Leaf leaf3 = new Leaf("Leaf 3");composite1.add(leaf3);root.add(leaf1);root.add(leaf2);root.add(composite1);root.operation(); // This will invoke the operation method for the whole structure}
}
4.2 代码分析
- 组件接口(Component):定义了所有组件都必需实现的接口。这样,客户端可以使用统一的方式来操作。
- 叶子节点(Leaf):实现组件接口,表示不能再加入子节点的对象,定义具体的业务逻辑。
- 树枝节点(Composite):实现组件接口,持有所有子组件并实现对它们的管理,包括添加和移除子组件的功能。
- 客户端:通过创建组合结构来组织组件,使得用户可以轻松操作复杂的对象结构。
5. 工作流程
- 定义组件接口:创建一个接口,提供所有组件需要实现的方法。
- 创建叶子节点类:实现组件接口,定义基本操作和具体业务。
- 创建树枝节点类:实现组件接口,管理子组件,包括添加、删除和操作子组件。
- 客户端使用组合:通过创建组合对象来添加叶子节点和其他树枝节点,统一管理整个结构。
6. 变种
- 递归组合:可以实现更复杂的组合,通过子组合继续组合形成多层结构。
- 安全组合:结合访问控制,只允许特定对组合的访问方式,以控制树的完整性。
7. 实际应用
组合模式在实际应用中广泛存在,以下是一些典型应用场景:
- 文件系统:文件和目录之间的关系可以用组合模式表示,目录可以包含文件和其它目录。
- GUI 组件:在图形用户界面中,组件和容器(如窗口、面板)之间的关系可以用组合模式管理。
- 组织结构:处理公司或团队的组织结构,部门(树枝节点)可以包含员工(叶子节点)、其他部门(树枝节点)等。
8. 使用场景
使用组合模式的场景包括:
- 当客户端需要统一处理单个对象和组合对象时。
- 当你需要用树形结构表现对象的组合关系时。
- 当你希望能够增加新的叶子和组合节点而无须改变现有代码时。
9. 优缺点
优点
- 简化客户端代码:客户端通过统一的接口与组件交互,无需关心树的结构。
- 灵活性:可以轻松添加新叶子和新的组合、维持已有结构。
- 高层次的透明性:客户端可以一致地对待树的节点和组合。
缺点
- 实现复杂性:逻辑上的复杂性可能会增加,特别是在处理组合时。
- 性能问题:对于非常深的组合结构,可能会造成性能问题,推迟操作实现。
10. 最佳实践
- 避免过度组合:组合结构应适度,避免组合生成过长的结构,减低可维护性。
- 使用统一接口:确保所有组件实现统一的接口,以增加灵活性和可扩展性。
- 固定接口设计:组件接口应尽量保持稳定以避免频繁的修改。
11. 注意事项
- 管理树的变化:设计树的结构时,避免频繁修改或调整结构,以防引入逻辑错误。
- 处理复杂性:注意过度设计,简单结构需保持简单。
- 性能监测:考虑树的深度和广度,在性能敏感的场景中小心使用。
12. 常见的误区
- 组合模式仅适用于树形结构:实际上,它可以用于其他潜在的组合关系,具备组织的灵活性。
- 认为组合模式只为复杂系统设计:组合模式同样适用于简单的、几乎不复杂的系统结构,以保持强一致性。
13. 常见问题
-
如何判断使用组合模式呢?
- 通常在有“部分-整体”结构需要处理时,就考虑使用组合模式。
-
组合模式的核心组成部分是什么?
- 树形结构的组成部分有组件接口、叶子节点类、树枝节点类和客户端。
-
组合模式如何处理节点的状态变化?
- 通过组件接口中的方法定义所需的状态变更,树的任何节点均可变化并影响整个结构。
14. 总结
组合模式是一种强大的设计模式,它简化了树形结构中复杂对象的管理与交互。通过建立一个统一接口,使得客户端能够轻松操作组合的对象,增强了代码的可读性、可维护性和扩展性。在实际开发中,合理运用组合模式不仅能够提升软件的质量,还能有效管理复杂的业务需求。通过对组合模式的掌握与经验积累,开发者能更好地设计出灵活、易扩展的应用程序。
相关文章:
Java设计模式:结构型模式→组合模式
Java 组合模式详解 1. 定义 组合模式(Composite Pattern)是一种结构型设计模式,它允许将对象组合成树形结构以表示“部分-整体”的层次。组合模式使得客户端能够以统一的方式对待单个对象和对象集合的一致性,有助于处理树形结构…...
【福州市AOI小区面】shp数据学校大厦商场等占地范围面数据内容测评
AOI城区小区面样图和数据范围查看: — 字段里面有name字段。分类比较多tpye:每个值代表一个类型。比如字段type中1549代表小区住宅,1563代表学校。小区、学校等占地面积范围数据 —— 小区范围占地面积面数据shp格式 无偏移坐标,只…...
【Python实现机器遗忘算法】复现2023年TNNLS期刊算法UNSIR
【Python实现机器遗忘算法】复现2023年TNNLS期刊算法UNSIR 1 算法原理 Tarun A K, Chundawat V S, Mandal M, et al. Fast yet effective machine unlearning[J]. IEEE Transactions on Neural Networks and Learning Systems, 2023. 本文提出了一种名为 UNSIR(Un…...
基于SpringBoot的阳光幼儿园管理系统
作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:…...
【逻辑学导论第15版】A. 推理
识别下列语段中的前提与结论。有些前提确实支持结论,有些并不支持。请注意,前提可能直接或间接地支持结论,而简单的语段也可能包含不止一个论证。 例题: 1.管理得当的民兵组织对于一个自由国家的安全是必需的,因而人民…...
【开源免费】基于SpringBoot+Vue.JS景区民宿预约系统(JAVA毕业设计)
本文项目编号 T 162 ,文末自助获取源码 \color{red}{T162,文末自助获取源码} T162,文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程3.1 启动教程3.2 讲解视频3.3 二次开发教程 四、功能截图五、文案资料5.1 选题背景5.2 国内…...
c++ map/multimap容器 学习笔记
1 map的基本概念 简介: map中所有的元素都是pair pair中第一个元素是key(键),第二个元素是value(值) 所有元素都会根据元素的键值自动排序。本质: map/multimap 属于关联式容器,底…...
安卓逆向之脱壳-认识一下动态加载 双亲委派(一)
安卓逆向和脱壳是安全研究、漏洞挖掘、恶意软件分析等领域的重要环节。脱壳(unpacking)指的是去除应用程序中加固或保护措施的过程,使得可以访问应用程序的原始代码或者数据。脱壳的重要性: 分析恶意软件:很多恶意软件…...
64位的谷歌浏览器Chrome/Google Chrome
64位的谷歌浏览器Chrome/Google Chrome 在百度搜索关键字:chrome,即可下载官方的“谷歌浏览器Chrome/Google Chrome”,但它可能是32位的(切记注意网址:https://www.google.cn/...., 即:google.cnÿ…...
马尔科夫模型和隐马尔科夫模型区别
我用一个天气预报和海藻湿度观测的比喻来解释,保证你秒懂! 1. 马尔可夫模型(Markov Model, MM) 特点:状态直接可见 场景:天气预报(晴天→雨天→阴天…)核心假设: 下一个…...
Python NumPy(7):连接数组、分割数组、数组元素的添加与删除
1 连接数组 函数描述concatenate连接沿现有轴的数组序列stack沿着新的轴加入一系列数组。hstack水平堆叠序列中的数组(列方向)vstack竖直堆叠序列中的数组(行方向) 1.1 numpy.concatenate numpy.concatenate 函数用于沿指定轴连…...
【LLM】deepseek多模态之Janus-Pro和JanusFlow框架
note 文章目录 note一、Janus-Pro:解耦视觉编码,实现多模态高效统一技术亮点模型细节 二、JanusFlow:融合生成流与语言模型,重新定义多模态技术亮点模型细节 Reference 一、Janus-Pro:解耦视觉编码,实现多模…...
2000-2021年 全国各地级市专利申请与获得情况、绿色专利申请与获得情况数据
2000-2021年 全国各地级市专利申请与获得情况、绿色专利申请与获得情况数据.ziphttps://download.csdn.net/download/2401_84585615/89575931 https://download.csdn.net/download/2401_84585615/89575931 2000至2021年,全国各地级市的专利申请与获得情况呈现出显著…...
51单片机(STC89C52)开发:点亮一个小灯
软件安装: 安装开发板CH340驱动。 安装KEILC51开发软件:C51V901.exe。 下载软件:PZ-ISP.exe 创建项目: 新建main.c 将main.c加入至项目中: main.c:点亮一个小灯 #include "reg52.h"sbit LED1P2^0; //P2的…...
数仓ETL测试
提取,转换和加载有助于组织使数据在不同的数据系统中可访问,有意义且可用。ETL工具是用于提取,转换和加载数据的软件。在当今数据驱动的世界中,无论大小如何,都会从各种组织,机器和小工具中生成大量数据。 …...
240. 搜索二维矩阵||
参考题解:https://leetcode.cn/problems/search-a-2d-matrix-ii/solutions/2361487/240-sou-suo-er-wei-ju-zhen-iitan-xin-qin-7mtf 将矩阵旋转45度,可以看作一个二叉搜索树。 假设以左下角元素为根结点, 当target比root大的时候ÿ…...
反向代理模块b
1 概念 1.1 反向代理概念 反向代理是指以代理服务器来接收客户端的请求,然后将请求转发给内部网络上的服务器,将从服务器上得到的结果返回给客户端,此时代理服务器对外表现为一个反向代理服务器。 对于客户端来说,反向代理就相当于…...
Kafka的内部通信协议
引言 kafka内部用到的常见协议和优缺点可以看看原文 Kafka用到的协议 本文奖详细探究kafka核心通信协议和高性能的关键 网络层通信的实现 基于 Java NIO:Kafka 的网络通信层主要基于 Java NIO 来实现,这使得它能够高效地处理大量的连接和数据传输。…...
Excel - Binary和Text两种Compare方法
Option Compare statement VBA里可以定义默认使用的compare方法: Set the string comparison method to Binary. Option Compare Binary That is, "AAA" is less than "aaa". Set the string comparison method to Text. Option Compare Tex…...
【Linux权限】—— 于虚拟殿堂,轻拨密钥启华章
欢迎来到ZyyOvO的博客✨,一个关于探索技术的角落,记录学习的点滴📖,分享实用的技巧🛠️,偶尔还有一些奇思妙想💡 本文由ZyyOvO原创✍️,感谢支持❤️!请尊重原创…...
EasyExcel使用详解
文章目录 EasyExcel使用详解一、引言二、环境准备与基础配置1、添加依赖2、定义实体类 三、Excel 读取详解1、基础读取2、自定义监听器3、多 Sheet 处理 四、Excel 写入详解1、基础写入2、动态列与复杂表头3、样式与模板填充 五、总结 EasyExcel使用详解 一、引言 EasyExcel 是…...
LeetCode 2412.完成所有交易的初始最少钱数:【年度巨献】举例说明(讲明白),由难至简(手脚不乱),附Python一行版
【LetMeFly】2412.完成所有交易的初始最少钱数:【年度巨献】举例说明(讲明白),由难至简(手脚不乱),附Python一行版 文章目录 【LetMeFly】2412.完成所有交易的初始最少钱数:【年度巨献】举例说明(讲明白),由难至简(手脚…...
前端-Rollup
Rollup 是一个用于 JavaScript 的模块打包工具,它将小的代码片段编译成更大、更复杂的代码,例如库或应用程序。它使用 JavaScript 的 ES6 版本中包含的新标准化代码模块格式,而不是以前的 CommonJS 和 AMD 等特殊解决方案。ES 模块允许你自由…...
ubuntu黑屏问题解决
重启Ubuntu后,系统自动进入tty1,无法进入桌面。想到前几天安装了一些主题之类的,然后今天才重启,可能是这些主题造成冲突或者问题了把。 这里直接重新安装ubuntu-desktop解决: 更新源: sudo apt-get upd…...
MV结构下设置Qt表格的代理
目录 预备知识 模型 关联 刷新 示例 代理 模型 界面 结果 完整资料见: 所谓MV结构,是“model-view”(模型-视图)的简称。也就是说,表格的数据保存在model中,而视图由view实现。在我前面的很多博客…...
vue3相关知识点
title: vue_1 date: 2025-01-28 12:00:00 tags:- 前端 categories:- 前端vue3 Webpack ~ vite vue3是基于vite创建的 vite 更快一点 一些准备工作 准备后如图所示 插件 Main.ts // 引入createApp用于创建应用 import {createApp} from vue // 引入App根组件 import App f…...
Lustre v6 语法 - 时序表达式
概述 Lustre v6 语法中,与时序表达式有关的运算,包括 ->(followed by), pre(previous), fby, current, when, merge。其中,除 merge 运算是 Lustre v6 中新引入的外,其余在 Lustre Core 语法中已有定义。 与时序表达式有关的…...
vs2013 使用 eigen 库编译时报 C2059 错的解决方法
(个人感觉)vs2013 就不能使用版本大于等于 3.4 的 eigen,使用 3.3.9 就可以了,再不行就用 3.3.8 另一个博主也遇到过用 vs2013 的时候不能编译 3.4 的 eigen 的问题,不过我用的是 win11,所以感觉跟操作系统…...
Kafka 消费端反复 Rebalance: `Attempt to heartbeat failed since group is rebalancing`
文章目录 Kafka 消费端反复 Rebalance: Attempt to heartbeat failed since group is rebalancing1. Rebalance 过程概述2. 错误原因分析2.1 消费者组频繁加入或退出2.1.1 消费者故障导致频繁重启2.1.2. 消费者加入和退出导致的 Rebalance2.1.3 消费者心跳超时导致的 Rebalance…...
【第九天】零基础入门刷题Python-算法篇-数据结构与算法的介绍-六种常见的图论算法(持续更新)
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、Python数据结构与算法的详细介绍1.Python中的常用的图论算法2. 图论算法3.详细的图论算法1)深度优先搜索(DFS)2…...
