Java设计模式-组合模式

组合模式

1.组合模式含义

组合模式,将对象组合成树形结以表示部分-整体的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性

组合模式可以简单的理解为将各个单独的小对象,通过组合模式,组合成一个大的对象,这个大的对象里面包含了父子节点这样的结构。如果实现过树形结构需求的小伙伴应该能比较快速的接受这个模式。

2.代码示例

下面先以一个简单的代码示例,来展示一下组合模式的代码结构

2.1Component类

Component类是组合对象的抽象类

public abstract class Component {protected String name;public Component(String name) {this.name = name;}public abstract void add(Component component);public abstract void remove(Component component);public abstract void display(int depth);
}

2.2Leaf类

Leaf类是Component的子类,是叶子节点类,叶子节点只有对象本身的名称信息,没有子节点信息

public class Leaf extends Component{public Leaf(String name) {super(name);}@Overridepublic void add(Component component) {System.out.println("新增一个叶子节点");}@Overridepublic void remove(Component component) {System.out.println("删除一个叶子节点");}@Overridepublic void display(int depth) {for (int i = 0; i < depth; i++) {System.out.print("-");}System.out.println(name);}
}

2.3 Composite类

Composite类是Component类的子类,是根节点或者中间节点类,既有节点本身的名称信息,也有叶子节点的信息

public class Composite extends Component{private List<Component> childrenList = new ArrayList<>();public Composite(String name) {super(name);}@Overridepublic void add(Component component) {childrenList.add(component);}@Overridepublic void remove(Component component) {childrenList.remove(component);}@Overridepublic void display(int depth) {for (int i = 0; i < depth; i++) {System.out.print("-");}System.out.println(name);for (Component component : childrenList) {component.display(depth + 4);}}
}

2.4测试类

public class MainApp {public static void main(String[] args) {Composite root = new Composite("root");root.add(new Leaf("root的A叶子"));root.add(new Leaf("root的B叶子"));Composite comp = new Composite("root的X子节点");comp.add(new Leaf("X子节点的叶子节点C"));comp.add(new Leaf("X子节点的叶子节点D"));root.add(comp);Composite compY = new Composite("X节点的Y子节点");compY.add(new Leaf("Y子节点的叶子节点E"));compY.add(new Leaf("Y子节点的叶子节点F"));comp.add(compY);Leaf leaf = new Leaf("叶子G");root.add(leaf);root.remove(leaf);root.display(2);}
}

运行结果

–root
------root的A叶子
------root的B叶子
------root的X子节点
----------X子节点的叶子节点C
----------X子节点的叶子节点D
----------X节点的Y子节点
--------------Y子节点的叶子节点E
--------------Y子节点的叶子节点F

这个结果其实就是如下这个图片的展示效果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MgmN3Auh-1689863412527)(C:\Users\dalei\AppData\Roaming\Typora\typora-user-images\image-20230719213141794.png)]

就是这样的树形结构。

将各个单独的对象,组合起来,组合成这样的树形结构,这就是组合模式

3.总结

当我们的需求中是体现部分与整体层次的结构时,以及希望用户可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时,就可以考虑使用组合模式了。

组合模式中,Leaf叶子节点并没有子节点了,但是却还有add和remove方法,这样做看似有些多余,因为即使调用了子节点的add或remove方法也不会真的增加和删除孩子节点。

此处这样实现其实是涉及到透明方式的选择。也就是说在Component中所声明的用来管理子对象的方法,其中包括add和remove等。这样实现Component接口的所有子类都聚类了add和remove。这样做的好处是叶子节点和中间节点对于外界来说没有区别,它们具备完全一致的行为接口。但是问题也很明显,因为叶子节点的add和remove功能并没有效果。

如果希望在叶子节点中不要实现add和remove方法,就要以安全方式来使用,也就是在Component类中不去声明add和remove,那么子类也就不需要实现这些方法。取而代之的是将这些方法放到中间节点去实现,这样做就不会有上面的透明方式实现的问题了。但是也正因为不够透明,所以叶子节点和中间节点将不会有相同的方法接口,客户端在调用的时候需要做相应的判断,使用上不太方便。

但是其实透明方式不透明方式实现组合模式都是可以的,看具体开发中哪种方法更适合即可。

实现这些方法。取而代之的是将这些方法放到中间节点去实现,这样做就不会有上面的透明方式实现的问题了。但是也正因为不够透明,所以叶子节点和中间节点将不会有相同的方法接口,客户端在调用的时候需要做相应的判断,使用上不太方便。

但是其实透明方式不透明方式实现组合模式都是可以的,看具体开发中哪种方法更适合即可。

组合模式的好处是:基本你对象可以被组合成更复杂的对象,而这个组合对象又可以被组合,这样不断递归下去,客户端任何用到基本对象的地方都可以使用组合对象了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/6739.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LiveNVR监控流媒体Onvif/RTSP功能-支持无人机、IPC等设备RTMP推流转码分发H5无插件播放也支持GB28181输出

LiveNVR支持无人机、IPC等设备RTMP推流转码分发H5无插件播放也支持GB28181输出 1、无人机推流转国标2、获取RTMP推流地址2.1、RTMP推流地址格式2.2、推流地址示例 2、设备RTMP推流3、配置拉转RTMP3.1、直播流地址格式3.2、直播流地地址示例3.3、通道配置直播流地址 4、配置级联…

深入浅出多种开发语言对接淘宝京东1688阿里巴巴等电商平台,获取实时商品详情数据API接口介绍

api接口详解大全?优秀的设计是产品变得卓越的原因设计API意味着提供有效的接口&#xff0c;可以帮助API使用者更好地了解、使用和集成&#xff0c;同时帮助人们有效地维护它每个产品都需要使用手册&#xff0c;API也不例外在API领域&#xff0c;可以将设计视为服务器和客户端之…

IDE /完整分析C4819编译错误的本质原因

文章目录 概述基本概念代码页标识符字符集和字符编码方案源字符集和执行字符集 编译器使用的字符集VS字符集配置 有何作用编译器 - 源字符集编译器 -执行字符集 Qt Creator下配置MSVC编译器参数动态库DLL字符集配置不同于可执行程序EXE总结 概述 本文将从根本原因上来分析和解…

属猴人性格及一生运势怎么样?

生肖属猴的人聪明&#xff0c;才华出众&#xff0c;是个非常会处理人际关系的生肖&#xff0c; 开朗&#xff0c;大方&#xff0c;人缘好&#xff0c;而且能说会道&#xff0c;嘴巴甜&#xff0c;也特别擅长社交&#xff0c;喜欢热闹&#xff0c; 所以属猴人不管在哪都容易受到…

数仓学习---13、报表数据导出

星光下的赶路人star的个人主页 莫见长安行乐处&#xff0c;空令岁月易蹉跎 文章目录 一、报表数据导出1.1 MySQL建库建表1.1.1 创建数据库1.1.2 创建表 1.2 数据导出1.2.1 DataX配置文件生成脚本1.2.2 编写每日导出脚本 一、报表数据导出 为方便报表应用使用数据&#xff0c;需…

Java诊断利器 Arthas-- 一款释放潜力的神器

嘿&#xff0c;你是不是对Java开发中的调试和诊断问题感到头疼&#xff1f; 别担心&#xff0c;我要告诉你一个秘密武器&#xff01;它就像是一位超级英雄&#xff0c;能够释放你的潜力&#xff0c;解决你的烦恼&#xff01;它的名字叫做Arthas&#xff0c;是一款Java诊断利器…

手写Nacos基本原理——服务注册 配置管理

手写Nacos基本原理 一、背景介绍二、 思路方案三、过程nacosService代码pom文件配置文件具体类 nacosSDK代码pom文件配置类具体类 serviceA代码pom文件配置文件具体类 serviceB代码pom文件配置文件具体类 实现效果四、总结五、升华 一、背景介绍 之前在项目开发的过程中&#…

Spring Cache的介绍以及使用方法、常用注解

一、Spring Cache介绍 Spring Cache是一个框架&#xff0c;实现了基于注解的缓存功能&#xff0c;只需要简单地加一个注解&#xff0c;就能实现缓存功能. Spring Cache提供了一层抽象&#xff0c;底层可以切换不同的cache实现。具体就是通过CacheManager接口来统一不同的缓存…

C# List 详解五

目录 26.GetType() 27.IndexOf(T) 28.IndexOf(T, Int32) 29.IndexOf(T, Int32, Int32) 30.Insert(Int32, T) 31.InsertRange(Int32, IEnumerable) 32.LastIndexOf(T) 33.LastIndexOf(T, Int32) 34.LastIndexOf(T, Int32, Int32) …

【CAS6.6源码解析】调试Rest API接口

CAS的web层默认是基于webflow实现的&#xff0c;ui和后端是耦合在一起的&#xff0c;做前后端分离调用和调试的时候不太方便。但是好在CAS已经添加了支持Rest API的support模块&#xff0c;添加相应模块即可。 文章目录 添加依赖并重新build效果 添加依赖并重新build 具体添加…

32位Cortex-M4 MCU:LPC54607J256ET180E、LPC54605J512BD100K 180MHz嵌入式微控制器

LPC546xx 32 位微控制器(MCU) 具有丰富的外设集、极低的功耗和增强的调试功能。 LPC546xx MCU系列采用ARM Cortex-M4内核&#xff0c;可提供以太网支持&#xff0c;并设有一个TFT LCD控制器和两个CAN FD模块。LPC546xx MCU旨在提高灵活性和性能可扩展性&#xff0c;可提供高达1…

http-为什么文件上传要转成Base64

# 前言 最近在开发中遇到文件上传采用Base64的方式上传&#xff0c;记得以前刚开始学http上传文件的时候&#xff0c;都是通过content-type为multipart/form-data方式直接上传二进制文件&#xff0c;我们知道都通过网络传输最终只能传输二进制流&#xff0c;所以毫无疑问他们本…

【数据库SQLite】SQLite 约束

约束是在表的数据列上强制执行的规则。这些是用来限制可以插入到表中的数据类型。这确保了数据库中数据的准确性和可靠性。约束可以是列级或表级。列级约束仅适用于列&#xff0c;表级约束被应用到整个表。 常见 SQLite 约束汇总&#xff1a; NOT NULL 约束&#xff1a;确保某…

Vue3 Vite electron 开发桌面程序

Electron是一个跨平台的桌面应用程序开发框架&#xff0c;它允许开发人员使用Web技术&#xff08;如HTML、CSS和JavaScript&#xff09;构建桌面应用程序&#xff0c;这些应用程序可以在Windows、macOS和Linux等操作系统上运行。 Electron的核心是Chromium浏览器内核和Node.js…

CentOS 7.6安装 MongoDB 5.0.2

https://developer.aliyun.com/article/983777 我遇到的问题&#xff1a;如何以集群的方式启动&#xff0c;使用replSet的方式进行启动&#xff1a; 需要在配置文件上加上replSet的信息 port27017 #端口 bind_ip0.0.0.0 #默认是127.0.0.1 dbpath/usr/local/mongodb/data #数据…

ABAP 为N的一个数,在原来基础上浮动在-30~30

需求&#xff1a;为N的一个数&#xff0c;在原来基础上浮动在-30~30 *&---------------------------------------------------------------------* *& Report ZZZZ111 *&---------------------------------------------------------------------* *& 需求&…

【算法基础:搜索与图论】3.4 求最短路算法(Dijkstrabellman-fordspfaFloyd)

文章目录 求最短路算法总览Dijkstra朴素 Dijkstra 算法&#xff08;⭐原理讲解&#xff01;⭐重要&#xff01;&#xff09;&#xff08;用于稠密图&#xff09;例题&#xff1a;849. Dijkstra求最短路 I代码1——使用邻接表代码2——使用邻接矩阵 补充&#xff1a;稠密图和稀疏…

libtorch水下图像增强模型和基准数据集

水下图像增强由于其在海洋工程和水上机器人领域的重要性而备受关注。在过去的几年里,人们提出了许多水下图像增强算法。然而,这些算法主要使用合成数据集或少数选定的真实世界图像进行评估。因此,目前还不清楚这些算法如何处理在野外获取的图像,以及我们如何衡量该领域的进…

npm i babel-plugin-import -D之后报错

替换modules/.bin/XX文件 1.vue-cli-service #!/bin/sh basedir$(dirname "$(echo "$0" | sed -e s,\\,/,g)")case uname in*CYGWIN*) basedircygpath -w "$basedir";; esacif [ -x "$basedir/node" ]; then"$basedir/node"…

【NLP】视觉变压器与卷积神经网络

一、说明 本篇是 变压器因其计算效率和可扩展性而成为NLP的首选模型。在计算机视觉中&#xff0c;卷积神经网络&#xff08;CNN&#xff09;架构仍然占主导地位&#xff0c;但一些研究人员已经尝试将CNN与自我注意相结合。作者尝试将标准变压器直接应用于图像&#xff0c;发现在…