(十 一)趣学设计模式 之 组合模式!

目录
- 一、 啥是组合模式?
- 二、 为什么要用组合模式?
- 三、 组合模式的实现方式
- 四、 组合模式的优缺点
- 五、 组合模式的应用场景
- 六、 总结
🌟我的其他文章也讲解的比较有趣😁,如果喜欢博主的讲解方式,可以多多支持一下,感谢🤗!
🌟了解外观模式请看: (十)趣学设计模式 之 外观模式!
这篇文章带你详细认识一下设计模式中的外观模式
一、 啥是组合模式?
想象一下,你正在整理你的电脑文件 📁。 你有文件,也有文件夹。 文件夹里可以包含文件,也可以包含其他文件夹。 你可以对文件和文件夹进行统一的操作,比如复制、删除、移动等等 ✂️。

组合模式,就是将对象组合成树形结构以表示“整体-部分”的层次结构! 组合模式使得用户对单个对象和组合对象的使用具有一致性 🌳。
简单来说,就是把一组相似的对象组织成树状结构,方便统一管理和操作! 🌲
- 你想表示“整体-部分”的层次结构: 就像文件夹包含文件和文件夹 📁!
- 你想让客户端可以统一地处理单个对象和组合对象: 就像你可以对文件和文件夹进行统一的复制、删除操作 ✂️!
- 你想忽略单个对象和组合对象之间的差异: 就像你不想区分文件和文件夹,都把它们当作“文件系统对象”来处理 📁📄!
二、 为什么要用组合模式?
用组合模式,好处多多 👍:
- 表示层次结构: 可以清晰地表示“整体-部分”的层次结构 🌳!
- 统一操作: 可以统一地操作单个对象和组合对象 ✂️!
- 简化客户端代码: 客户端不需要区分单个对象和组合对象,代码更简洁 🧹!
- 扩展性好: 可以方便地添加新的叶子节点和组合节点 ➕!
三、 组合模式的实现方式
组合模式主要包含以下几个角色:
- Component(组件): 定义组合中叶子节点和组合节点的通用接口。 📁📄 (比如:文件系统对象)
- Leaf(叶子节点): 表示组合中的叶子节点,没有子节点。 📄 (比如:文件)
- Composite(组合节点): 表示组合中的组合节点,可以包含叶子节点和其他组合节点。 📁 (比如:文件夹)
代码示例:
import java.util.ArrayList;
import java.util.List;// 组件:文件系统对象
public abstract class FileSystemObject {protected String name; // 名称protected int level = 0; // 层次级别public FileSystemObject(String name) {this.name = name;}public abstract void display(); // 显示// 设置层次级别public void setLevel(int level) {this.level = level;}// 获取缩进字符串protected String getIndentString() {StringBuilder sb = new StringBuilder();for (int i = 0; i < level; i++) {sb.append(" "); // 两个空格缩进}return sb.toString();}
}// 叶子节点:文件
public class File extends FileSystemObject {public File(String name) {super(name);}@Overridepublic void display() {System.out.println(getIndentString() + "文件:" + name);}
}// 组合节点:文件夹
public class Directory extends FileSystemObject {private List<FileSystemObject> children = new ArrayList<>(); // 子节点public Directory(String name) {super(name);}public void add(FileSystemObject fileSystemObject) {children.add(fileSystemObject);}public void remove(FileSystemObject fileSystemObject) {children.remove(fileSystemObject);}@Overridepublic void display() {System.out.println(getIndentString() + "文件夹:" + name);for (FileSystemObject child : children) {child.setLevel(this.level + 1); // 设置子节点的层次级别child.display();}}
}// 客户端
public class Client {public static void main(String[] args) {Directory root = new Directory("根目录"); // 创建根目录Directory dir1 = new Directory("目录1"); // 创建目录1File file1 = new File("文件1.txt"); // 创建文件1File file2 = new File("文件2.txt"); // 创建文件2root.add(dir1); // 将目录1添加到根目录root.add(file1); // 将文件1添加到根目录dir1.add(file2); // 将文件2添加到目录1root.display(); // 显示根目录}
}
分析:
FileSystemObject是组件,定义了文件系统对象的通用接口。File是叶子节点,表示文件。Directory是组合节点,表示文件夹,可以包含文件和文件夹。
输出结果:
文件夹:根目录文件夹:目录1文件:文件2.txt文件:文件1.txt
四、 组合模式的优缺点
优点:
- 表示层次结构 🌳!
- 统一操作 ✂️!
- 简化客户端代码 🧹!
- 扩展性好 ➕!
缺点:
- 设计较复杂,客户端需要花更多时间理清类之间的层次关系 😫!
- 不容易限制组合中的组件类型,可能会导致运行时错误 💥!
五、 组合模式的应用场景
- 你想表示“整体-部分”的层次结构: 就像文件系统 📁!
- 你想让客户端可以统一地处理单个对象和组合对象: 就像你可以对文件和文件夹进行统一的复制、删除操作 ✂️!
- GUI组件: GUI组件通常是树形结构,比如窗口包含按钮、文本框等组件。
- 组织结构: 公司组织结构可以表示为树形结构,部门包含员工和子部门。
六、 总结
- 组合模式就像把一组相似的对象组织成树状结构,方便统一管理和操作! 🌲
- 主要包含组件、叶子节点和组合节点三个角色! 🎭
- 优点是表示层次结构、统一操作、简化客户端代码、扩展性好! 👍
- 缺点是设计较复杂、不容易限制组合中的组件类型! 👎
- 适用于需要表示“整体-部分”的层次结构,或者需要统一地处理单个对象和组合对象的场景! 🎯
希望这篇文章能让你彻底理解组合模式! 💯 祝你学习愉快! 😄
看完请看:(十 二)趣学设计模式 之 享元模式!
相关文章:
(十 一)趣学设计模式 之 组合模式!
目录 一、 啥是组合模式?二、 为什么要用组合模式?三、 组合模式的实现方式四、 组合模式的优缺点五、 组合模式的应用场景六、 总结 🌟我的其他文章也讲解的比较有趣😁,如果喜欢博主的讲解方式,可以多多支…...
安全模块设计:token服务、校验注解(开启token校验、开启签名校验、允许处理API日志)、获取当前用户信息的辅助类
文章目录 引言pom.xmlI 校验注解ApiValidationII token服务TokenService获取当前用户信息的辅助类III 域登录接口响应数据登陆用户信息引言 pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/PO…...
Python学习第十八天之深度学习之Tensorboard
Tensorboard 1.TensorBoard详解2.安装3.使用4.图像数据格式的一些理解 后续会陆续在词博客上更新Tensorboard相关知识 1.TensorBoard详解 TensorBoard是一个可视化的模块,该模块功能强大,可用于深度学习网络模型训练查看模型结构和训练效果(…...
Redis安装及其AnotherRedisDesktopManagera安装使用
一、Redis安装 1. 下载Redis安装包 通过网盘分享的文件:Redis 链接: https://pan.baidu.com/s/1elAT8mk3EIoYQQ3WoVVoNg?pwd7yrz 提取码: 7yrz 2. 解压Redis安装包 下载完成后,将Redis安装包解压到一个指定的目录,例如:C:\Re…...
C# dll文件的反编译获取源码
目录 前言操作流程结论 前言 上一篇文章介绍了将C# cs类文件加密为dll文件,在此给大家写一篇关于反编译dll文件的文章。 操作流程 首先,我们需要准备一个C#反编译工具,我这里用的是免费的软件JetBrains dotPeek,类似的有很多&am…...
大语言模型学习--LangChain
LangChain基本概念 ReAct学习资料 https://zhuanlan.zhihu.com/p/660951271 LangChain官网地址 Introduction | 🦜️🔗 LangChain LangChain是一个基于语言模型开发应用程序的框架。它可以实现以下应用程序: 数据感知:将语言模型…...
Spark内存迭代计算
一、宽窄依赖 窄依赖:父RDD的一个分区数据全部发往子RDD的一个分区 宽依赖:父RDD的一个分区数据发往子RDD的多个分区,也称为shuffle 二、Spark是如何进行内存计算的?DAG的作用?Stage阶段划分的作用? &a…...
Python之参数星号(*)使用笔记
背景 在学习python时发现方法调用和方法定义会经常发现有带星号的标记,为了弄明白是怎么使用的。特此做个笔记。 一、参数符号对比速查表 符号类使用场景作用描述示例无符号函数定义/调用普通位置参数或关键字参数.def func(a, b)*函数定义收集多余位置参数为元组…...
一文掌握 Scrapy 框架的详细使用,包括实战案例
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 1. Scrapy 简介2. Scrapy 的核心组件3. 安装 Scrapy4. 创建 Scrapy 项目4.1 创建项目4.2 创建 Spider5. 编写 Spider5.1 定义 Item5.2 编写 Spider 逻辑6. 运行 Scrapy 爬虫6.1 运行爬虫6.2 保存爬取数据7. Scrapy 的高…...
【Mac】git使用再学习
目录 前言 如何使用github建立自己的代码库 第一步:建立本地git与远程github的联系 生成密钥 将密钥加入github 第二步:创建github仓库并clone到本地 第三步:上传文件 常见的git命令 git commit git branch git merge/git rebase …...
【MySQL篇】数据库基础
目录 1,什么是数据库? 2,主流数据库 3,MySQL介绍 1,MySQL架构 2,SQL分类 3,MySQL存储引擎 1,什么是数据库? 数据库(Database,简称DB…...
SpringBoot项目注入 traceId 来追踪整个请求的日志链路
SpringBoot项目注入 traceId 来追踪整个请求的日志链路,有了 traceId, 我们在排查问题的时候,可以迅速根据 traceId 查找到相关请求的日志,特别是在生产环境的时候,用户可能只提供一个错误截图,我们作为开发…...
【Block总结】SAFMN,空间自适应调制与局部特征增强的协同设计|即插即用
论文信息 标题:Spatially-Adaptive Feature Modulation for Efficient Image Super-Resolution论文链接:https://arxiv.org/pdf/2302.13800代码与模型:https://github.com/sunny2109/SAFMN 创新点 空间自适应特征调制(SAFM&…...
Python爬虫:一文掌握PyQuery模块
文章目录 1. PyQuery 简介2. PyQuery 的安装2.1 安装 PyQuery2.2 安装依赖库3. PyQuery 的基本使用3.1 初始化 PyQuery 对象3.2 选择元素3.3 获取元素内容3.4 遍历元素4. PyQuery 的高级用法4.1 过滤元素4.2 查找子元素4.3 获取属性值4.4 修改元素4.5 添加和删除元素4.6 遍历文…...
LearnOpenGL之Shader编程用算法绘画
———————————————————— 前序 ——————————————————— AndroidLearnOpenGL是本博主自己实现的LearnOpenGL练习集合: Github地址:GitHub - wangyongyao1989/AndroidLearnOpenGL: OpenGL基础及运用 系列文章ÿ…...
如何使用Spring Boot框架整合Redis:超详细案例教程
目录 # 为什么选择Spring Boot与Redis整合? 1. 更新 pom.xml 2. 配置application.yml 3. 创建 Redis 配置类 4. Redis 操作类 5. 创建控制器 6. 启动应用程序 7. 测试 # 为什么选择Spring Boot与Redis整合? 将Spring Boot与Redis整合可以充分利…...
算法--贪心
贪心 原理经典例题[860. 柠檬水找零](https://leetcode.cn/problems/lemonade-change/description/)[2208. 将数组和减半的最少操作次数](https://leetcode.cn/problems/minimum-operations-to-halve-array-sum/description/)[179. 最大数](https://leetcode.cn/problems/large…...
线程控制(创建、终止、等待、分离)
目录 1.前言 2.创建线程 pthread_create函数 3.线程终止 pthread_exit函数 pthread_cancel函数 4.线程等待 5.线程分离 1.前言 在Linux系统中,并不存在真正的线程,只有轻量级进程。所以,Linux系统只提供了操作轻量级进程的系统调用…...
【备份】php项目处理跨域请求踩坑
这都是老生常谈的东西了。我还在踩坑,记录一下。 我在项目入口明明写了如下代码: // 处理预检请求 (OPTIONS) if ($_SERVER[REQUEST_METHOD] OPTIONS) {header("Access-Control-Allow-Origin: https://xxx.vip");header("Access-Cont…...
目标检测YOLO实战应用案例100讲-面向无人机图像的小目标检测
目录 知识储备 YOLO v8无人机拍摄视角小目标检测 数据集结构 环境部署说明 安装依赖 模型训练权重和指标可视化展示 训练 YOLOv8 PyQt5 GUI 开发 主窗口代码 main_window.py 使用说明 无人机目标跟踪 一、目标跟踪的基本原理 二、常用的目标跟踪算法 基于YOLOv…...
基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南
文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...
AI语音助手的Python实现
引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么?它的作用是什么? Spring框架的核心容器是IoC(控制反转)容器。它的主要作用是管理对…...
