设计模式之组合模式
目录
1、组合模式的定义
2、组合模式例子
3、组合模式实现
3.1 组合模式的结构
3.2 组合模式的分类
3.3 组合模式代码实现(透明组合模式)
4、组合模式的优点
5、组合模式使用场景
1、组合模式的定义
组合模式又名部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。
2、组合模式例子
生活中其实很多地方都体现了组合模式,最典型的便是我们使用的电脑里面的“目录”就是经典的组合模式。
目录由各种文件(如txt、word、PDF)、文件夹组成,一开始有个根文件夹,文件夹里面可以有各式各样的文件和文件夹,如下图:

这实际上就是典型的组合模式。下面我们来基于这个例子实现一下组合模式。
3、组合模式实现
3.1 组合模式的结构
组合模式主要包含三种角色:
- 抽象根节点(Component):定义系统各层次对象的共有方法和属性,可以预先定义一些默认行为和属性。
- 树枝节点(Composite):定义树枝节点的行为,存储子节点,组合树枝节点和叶子节点形成一个树形结构。
- 叶子节点(Leaf):叶子节点对象,其下再无分支,是系统层次遍历的最小单位。
3.2 组合模式的分类
在使用组合模式时,根据抽象构件类的定义形式,我们可将组合模式分为透明组合模式和安全组合模式两种形式:(看不懂这一块可以先看代码示例,本文拿透明组合模式来举例,安装组合模式和这种模式差不多,大家看完就明白了。)
①透明组合模式:
透明组合模式中,抽象根节点角色中声明了所有用于管理成员对象的方法,比如在我们接下来示例中AbstractFile声明了 createFile、deleteFile 、getFiles方法,这样做的好处是确保所有的构件类都有相同的接口。透明组合模式也是组合模式的标准形式。
透明组合模式的缺点是不够安全,因为叶子对象和容器对象在本质上是有区别的,叶子对象不可能
有下一个层次的对象,即不可能包含成员对象,因此为其提供 createFile()、deleteFile() 、getFiles()等方法是没有意义的,这在编译阶段不会出错,但在运行阶段如果调用这些方法可能会出错(如果没有提供相应的错误处理代码)
②安全组合模式:
在安全组合模式中,在抽象构件角色中没有声明任何用于管理成员对象的方法,而是在树枝节点
FileFolders类中声明并实现这些方法。
安全组合模式的缺点是不够透明,因为叶子构件和容器构件具有不同的方法,且容器构件中那些用于管理成员对象的方法没有在抽象构件类中定义,因此客户端不能完全针对抽象编程,必须有区别地对待叶子构件和容器构件。
3.3 组合模式代码实现(透明组合模式)
实际上我们上述的文件夹和各种文件(如word,PDF等)组成,因此我们可以这样来设计:设计一个抽象文件类(抽象根节点)、文件夹类(树枝节点)、普通文件类(叶子结点)。
抽象文件类(抽象根节点):
public abstract class AbstractFile { //抽象文件类private String name; //文件名private List<AbstractFile>list;//该结点下的子节点public void createFile(){ //在该节点下创建子节点throw new UnsupportedOperationException();}public void deleteFile(){ //删除子节点throw new UnsupportedOperationException();}public void getFiles(){ //获得所有子结点throw new UnsupportedOperationException();}public void setName(String name){ //重置名称this.name=name;}public String getName() { //获取名称return name;}public AbstractFile(String name) {this.name = name;}
}
文件夹类(树枝节点):
public class FileFolders extends AbstractFile { //文件夹类public FileFolders(String name) {super(name);}//注意!!!//只有文件夹才有子节点,所以文件夹可以重写这些方法的功能,否则调用会报错//由于为了方便理解,我们就模拟创建子节点、删除子节点了。@Overridepublic void createFile() {//模拟创建子节点System.out.println("创建子节点");}@Overridepublic void deleteFile() {//模拟删除子节点System.out.println("删除子节点");}@Overridepublic void getFiles() {//模拟获取所有子节点System.out.println("获取所有子节点");}
}
普通文件类:
public class myFile extends AbstractFile { //普通文件类public myFile(String name) {super(name);}
}
可见,此时如果我们想创建一个目录,只需先创建一个文件夹类作为根目录,然后可以对文件夹类进行增、删子节点的操作,这实际上和我们大家平时使用电脑是一样的,只不过我们通过组合模式将他们按“树形结构”组合了起来而已。
当然!这里我们实现的是透明组合模式,也就是虽然“普通文件类”也能有 createFile()、deleteFile() 、getFiles()等方法,这样好处我们上面说了,大家可以去看看,但是如果普通文件类调用这些方法,实际上是调用“AbstractFile类”的方法,而我们声明这些方法时,是直接抛出一个“UnsupportedOperationException”异常,因此保证了普通文件类无法创建子文件,这也是符合我们常理的,如下我们模拟一下上述操作:
测试代码:
public class Test {public static void main(String[] args) {myFile file = new myFile("一个普通文件");file.createFile();}
}
运行结果:
4、组合模式的优点
- 组合模式可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,它让客户端忽略了层次的差异,方便对整个层次结构进行控制。
- 客户端可以一致地使用一个组合结构或其中单个对象,不必关心处理的是单个对象还是整个组合结构,简化了客户端代码。
- 在组合模式中增加新的树枝节点和叶子节点都很方便,无须对现有类库进行任何修改,符合“开闭原则”。
- 组合模式为树形结构的面向对象实现提供了一种灵活的解决方案,通过叶子节点和树枝节点的递归组合,可以形成复杂的树形结构,但对树形结构的控制却非常简单。
5、组合模式使用场景
组合模式正是应树形结构而生,所以组合模式的使用场景就是出现树形结构的地方。比如:文件目录显示,多级目录呈现等树形结构数据的操作。
相关文章:
设计模式之组合模式
目录 1、组合模式的定义 2、组合模式例子 3、组合模式实现 3.1 组合模式的结构 3.2 组合模式的分类 3.3 组合模式代码实现(透明组合模式) 4、组合模式的优点 5、组合模式使用场景 1、组合模式的定义 组合模式又名部分整体模式,是用于把…...
计算机基础书籍
一操作系统 二常见问题总结 1.操作系统的特征? 并发、共享、虚拟、异步性 2.进程阻塞与唤醒的条件 等待 I/O 操作完成请求系统资源失败等待信号量或事件等待子进程结束被高优先级进程抢占 3.如何避免死锁? 1、避免资源竞争 2、破坏循环等待条件 3、优…...
保龄球游戏的获胜者、找出叠涂元素----2023/4/30
保龄球游戏的获胜者----2023/4/30 给你两个下标从 0 开始的整数数组 player1 和 player2 ,分别表示玩家 1 和玩家 2 击中的瓶数。 保龄球比赛由 n 轮组成,每轮的瓶数恰好为 10 。 假设玩家在第 i 轮中击中 xi 个瓶子。玩家第 i 轮的价值为: …...
jQuery事件
1. jQuery事件注册 单个事件注册 语法: element.事件(function(){}) eg:$(“div”).click(function(){ 事件处理程序 }) 其他事件和原生基本一致。比如mouseover、mouseout、blur、focus、change、keydown、keyup、resize、scroll 等 <!DOCTYP…...
初识SpringCloud
一、软件架构演进 单体架构 垂直架构 分布式架构 SOA架构 微服务架构 二、微服务架构 2.1 微服务理念 "微服务”一词源 于 Martin Fowler的名为 Microservices的博文,可以在他的官方博客上找到http://martinfowler.com/articles/microservices.html微服务是系统架构上…...
安装java配置
目录 安装JDK 编辑 环境变量配置 3、检验环境变量配置 二、安装tomcat 验证Tomcat配置是否成功 三、安装Mysql 一、安装 二、卸载 四、安装Maven 安装JDK 点击更改将C直接给为F即可。 点击确定后进行安装,安装完以后会提示安装JRE; 检测是否已经安装JDK的…...
KBO的选秀会有哪些规定和流程`棒球7号位
KBO(韩国职业棒球联盟)的选秀会有以下规定和流程: 1. 选秀对象:KBO的选秀会主要面向年满18岁及以上的高中和大学生,以及海外球员和自由球员。KBO的球队可以在选秀会中挑选所需的球员,每个球队有一定数量的选…...
男子订民宿被毁约5个家庭漂泊街头 房东:住满了,没办法
据媒体报道,5月1日,一位叫做诸先生的消费者和朋友们提前在平台上预订了五一假期前往青岛金沙滩地中海两天的别墅民宿,并支付了房款9600元。 但是当他们到达目的地前一个半小时联系房东时,却发现联系不上人。到达指定地点后&#x…...
Vue快速入门,常用指令,生命周期
Vue常用指令 案例: <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"…...
【热门框架】Mybatis-Plus入门介绍看这一篇文章就足够了
MyBatis-Plus 是在 MyBatis 的基础上进行了封装,提供了更加便捷的开发方式,具有简化开发、提高效率等优点。以下是 MyBatis-Plus 的一些特点和用法: 通用 CRUD 操作:MyBatis-Plus 提供了通用的 CRUD 接口,可以直接调用…...
Node【Node.js 20】新特性
文章目录 🌟前言🌟Node.js 20: 一次重要的升级和改进🌟Internationalization API Update🌟端口管理器🌟字符串处理🌟 更好的调试工具🌟 Crypto模块的更新🌟总结🌟写在最后…...
前端程序员的职业发展规划与路线——ChatGPT的回答
文章目录 一、前端程序员的职业规划是?回答1: 作为一个前端开发程序员,您的职业发展路线可能如下:回答2:作为前端开发程序员,您的职业发展路线可能如下:回答3: 你的职业发展路线可能…...
AlgoC++第八课:手写BP
目录 手写BP前言1. 数据加载2. 前向传播3. 反向传播总结 手写BP 前言 手写AI推出的全新面向AI算法的C课程 Algo C,链接。记录下个人学习笔记,仅供自己参考。 本次课程主要是手写 BP 代码 课程大纲可看下面的思维导图 1. 数据加载 我们首先来实现下MNIST…...
【Java笔试强训 27】
🎉🎉🎉点进来你就是我的人了博主主页:🙈🙈🙈戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔🤺🤺🤺 目录 一、选择题 二、编程题 🔥 不用加…...
java紫砂壶交易购物系统 mysql
网络紫砂壶可充通过色彩、图片、说明、设置动画加强了产品了宣传,大大达到了陶瓷业的“色型”要求。实现产品管理方便,起到立竿见影的效果,不用因为更改菜色而重新印刷。只要在后台鼠标轻轻一点,全线马上更新。采用B/S模式&#x…...
7-4 多态练习-计算面积
定义三个类,父类(抽象类)GeometricObject代表几何形状,子类Circle代表圆形,子类Rectangle代表矩形。具体属性和方法如下: 父类 (抽象类)GeometricObject 属性: private String color; private S…...
很佩服的一个Google大佬,离职了。。
这两天,科技圈又有一个突发的爆款新闻相信不少同学都已经看到了。 那就是75岁的计算机科学家Geoffrey Hinton从谷歌离职了,从而引起了科技界的广泛关注和讨论。 而Hinton自己也证实了这一消息。 提到Geoffrey Hinton这个名字,对于一些了解过…...
【Python习题集1】Python 语言基础知识
python习题 一、实验内容二、实验总结 一、实验内容 1、运用输入输出函数编写程序,将华氏温度转换成摄氏温度。换算公式:C(F-32)*5/9,其中C为摄氏温度,F为华氏温度。 (1)源代码: ffloat(input(输入华氏温…...
C语言进阶——数据在内存中的存储,你知道吗?
今天我们深度剖析数据在内存中的存储: 重点知识: 1、数据类型详细介绍 2、整形在内存中的存储:原码、反码、补码 3、大小端字节序介绍及判断 4、浮点型在内存中的存储解析 之前我们涉及关于这一部分的知识只是大致的进行讲解࿰…...
规则引擎----easy rules
一、规则引擎的作用 将复杂的if else判断剥离出来 二、使用 2.1、引入POM <!--easy rules核心库--><dependency><groupId>org.jeasy</groupId><artifactId>easy-rules-core</artifactId><version>3.3.0</version></depe…...
铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...
Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
系统掌握PyTorch:图解张量、Autograd、DataLoader、nn.Module与实战模型
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文通过代码驱动的方式,系统讲解PyTorch核心概念和实战技巧,涵盖张量操作、自动微分、数据加载、模型构建和训练全流程&#…...
基于鸿蒙(HarmonyOS5)的打车小程序
1. 开发环境准备 安装DevEco Studio (鸿蒙官方IDE)配置HarmonyOS SDK申请开发者账号和必要的API密钥 2. 项目结构设计 ├── entry │ ├── src │ │ ├── main │ │ │ ├── ets │ │ │ │ ├── pages │ │ │ │ │ ├── H…...
Python实现简单音频数据压缩与解压算法
Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中,压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言,提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...
Vue3 PC端 UI组件库我更推荐Naive UI
一、Vue3生态现状与UI库选择的重要性 随着Vue3的稳定发布和Composition API的广泛采用,前端开发者面临着UI组件库的重新选择。一个好的UI库不仅能提升开发效率,还能确保项目的长期可维护性。本文将对比三大主流Vue3 UI库(Naive UI、Element …...
相关类相关的可视化图像总结
目录 一、散点图 二、气泡图 三、相关图 四、热力图 五、二维密度图 六、多模态二维密度图 七、雷达图 八、桑基图 九、总结 一、散点图 特点 通过点的位置展示两个连续变量之间的关系,可直观判断线性相关、非线性相关或无相关关系,点的分布密…...
