当前位置: 首页 > news >正文

Java设计模式之组合模式

比如在实现一个文件管理系统时,对于客户端来说,如果需要区分文件与文件夹的使用,会比较麻烦,使用组合模式可以在使用不同对象时使用方法保持一致性。

定义

又名部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。

结构

组合模式主要包含三种角色:

抽象根节点:定义系统各层次对象的共有方法和属性,可以预先定义一些默认行为和属性。树枝节点:定义树枝节点的行为,存储子节点,组合树枝节点和叶子节点形成一个树形结构。

叶子节点:叶子节点对象,其下再无分支,是系统层次遍历的最小单位。

案例

简单实现一个文件管理系统

创建抽象跟结点 

//菜单组件包括文件夹与文件
public abstract class MenuComponent {protected String name; //组件名protected int level; //对应层级public String getName() {return name;}public void setName(String name) {this.name = name;}public int getLevel() {return level;}public void setLevel(int level) {this.level = level;}public void add(MenuComponent menuComponent){//文件不具备创建下级目录的功能,抛出不支持操作异常throw new UnsupportedOperationException();}//删除菜单及其子文件public void remove(MenuComponent menuComponent){throw new UnsupportedOperationException();}public void removeByIndex(int index){}//获取指定的子菜单public MenuComponent getChild(int i){throw new UnsupportedOperationException();}//输出本目录及其子目录public void print(){throw new UnsupportedOperationException();}
}

 创建树枝节点

//指文件夹
public class Menu extends MenuComponent {private List<MenuComponent> menuComponents = new ArrayList<>();public Menu(String name, int level) {this.name = name;this.level = level;}@Overridepublic void add(MenuComponent menuComponent) {menuComponents.add(menuComponent);}@Overridepublic void remove(MenuComponent menuComponent) {menuComponents.remove(menuComponent);}@Overridepublic void removeByIndex(int index) {menuComponents.remove(index);}@Overridepublic void print() {for (int i = 0; i < level; i++) {System.out.print("-");}System.out.println(name);for (MenuComponent menuComponent : menuComponents) {menuComponent.print();}}
}

创建叶子节点 

//指文件
public class MenuItem extends MenuComponent {public MenuItem(String name,int level){this.name = name;this.level = level;}@Overridepublic void print() {for (int i =0 ; i <level ; i++){System.out.print("-");}System.out.println(name);}
}

测试 

public class Client {public static void main(String[] args) {MenuComponent menuComponent = new Menu("主菜单",1);MenuComponent menu1 = new Menu("一级菜单1",2);MenuComponent menu2 = new Menu("一级菜单2",2);MenuComponent menu3 = new Menu("一级菜单3",2);MenuComponent menuItem1 = new MenuItem("二级菜单文件1",3);MenuComponent menuItem2 = new MenuItem("二级菜单文件2",3);MenuComponent menuItem3 = new MenuItem("二级菜单文件3",3);MenuComponent menuItem4 = new MenuItem("二级菜单文件4",3);MenuComponent menuItem5 = new MenuItem("二级菜单文件5",3);MenuComponent menuItem6 = new MenuItem("二级菜单文件6",3);MenuComponent menuItem7 = new MenuItem("二级菜单文件7",3);menuComponent.add(menu1);menuComponent.add(menu2);menuComponent.add(menu3);menu1.add(menuItem1);menu1.add(menuItem2);menu1.add(menuItem3);menu2.add(menuItem4);menu2.add(menuItem5);menu3.add(menuItem6);menu3.add(menuItem7);menuComponent.print();}
}

运行结果如下: 

-主菜单

--一级菜单1

---二级菜单文件1

---二级菜单文件2

---二级菜单文件3

--一级菜单2

---二级菜单文件4

---二级菜单文件5

--一级菜单3

---二级菜单文件6

---二级菜单文件7

组合模式的分类

在使用组合模式时,根据抽象构件类的定义形式,我们可将组合模式分为透明组合模式和安全组合模式两种形式。

  • 透明组合模式:透明组合模式中,抽象根节点角色中声明了所有用于管理成员对象的方法,比如在示例中 MenuComponent 声明了 add、remove 、getChild 方法,这样做的好处是确保所有的构件类都有相同的接口。透明组合模式也是组合模式的标准形式。透明组合模式的缺点是不够安全,因为叶子对象和容器对象在本质上是有区别的,叶子对象不可能有下一个层次的对象,即不可能包含成员对象,因此为其提供 add()、remove() 等方法是没有意义的,这在编译阶段不会出错,但在运行阶段如果调用这些方法可能会出错(如果没有提供相应的错误处理代码)
  • 安全组合模式:在安全组合模式中,在抽象构件角色中没有声明任何用于管理成员对象的方法,而是在树枝节点 Menu 类中声明并实现这些方法。安全组合模式的缺点是不够透明,因为叶子构件和容器构件具有不同的方法,且容器构件中那些用于管理成员对象的方法没有在抽象构件类中定义,因此客户端不能完全针对抽象编程,必须有区别地对待叶子构件和容器构件。

如果使用安全模式实现文件管理则不能使用多态的方法来创建对象,因为父类并不存在任何方法,不能通过子类对象去调用子类独有方法。

优点

  • 组合模式可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,它让客户端忽略了层次的差异,方便对整个层次结构进行控制。
  • 客户端可以一致地使用一个组合结构或其中单个对象,不必关心处理的是单个对象还是整个组合结构,简化了客户端代码。
  • 在组合模式中增加新的树枝节点和叶子节点都很方便,无须对现有类库进行任何修改,符合“开闭原则”。
  • 组合模式为树形结构的面向对象实现提供了一种灵活的解决方案,通过叶子节点和树枝节点的递归组合,可以形成复杂的树形结构,但对树形结构的控制却非常简单。

使用场景

组合模式正是应树形结构而生,所以组合模式的使用场景就是出现树形结构的地方。比如:文件目录显示,多级目录呈现等树形结构数据的操作。

相关文章:

Java设计模式之组合模式

比如在实现一个文件管理系统时&#xff0c;对于客户端来说&#xff0c;如果需要区分文件与文件夹的使用&#xff0c;会比较麻烦&#xff0c;使用组合模式可以在使用不同对象时使用方法保持一致性。 定义 又名部分整体模式&#xff0c;是用于把一组相似的对象当作一个单一的对…...

划词搜索IP插件

插件背景 浏览器插件可以让用户根据个人工作及日常需求来定制浏览器的功能和界面。当用户在网页上看到一些IP地址时&#xff0c;或许会好奇它们的来源和归属。传统的做法是&#xff0c;用户需要复制这个IP地址&#xff0c;然后跳转到埃文科技旗下的http://IPUU.net网站进行查询…...

LeetCode刷题---简单组(一)

文章目录 &#x1f352;题目一 507. 完美数&#x1f352;解法一 &#x1f352;题目二 2678. 老人的数目&#x1f352;解法一 &#x1f352;题目三 520. 检测大写字母&#x1f352;解法一&#x1f352;解法二 &#x1f352;题目一 507. 完美数 对于一个 正整数&#xff0c;如果它…...

如何能通过表面挖掘到深层次的底层思维?

如何能通过表面挖掘到深层次的底层思维&#xff1f; 挖掘深层次的底层思维是一项复杂且细致的工作&#xff0c;通常涉及到个人反思、观察、沟通和分析等多个方面。下面是一些可能会对你有帮助的策略和方法&#xff1a; 1. 提问的艺术 五次为什么&#xff1a;这是一种简单而有…...

【单片机学习笔记】Windows+Vscode+STM32F4+freeRTOS+FatFs gcc环境搭建

为摒弃在接受keil邮件&#xff0c;研究了下gun编译&#xff0c;以STM32F407为例&#xff0c;简单记录 1. 软件包准备 Git 选择对应版本直接安装即可https://git-scm.com/download/winmakegcc ​ 1&#xff09;将上述软件包放置于C盘根目录 2&#xff09;添加环境变量 3&am…...

Oracle 控制文件的作用与控制文件创建

1、控制文件存储的数据信息 1) 数据库名称和数据库唯一标识符 (DBID)&#xff0c;通过 select name,dbid from v$database; 查 询 DBID 和数据库名称 2) 创建数据库的时间戳 3) 有关数据文件、联机重做日志文件、归档重做日志文件的信息 4) 表空间信息 5) 检查点信息 6) 日志序…...

bootloader介绍

什么是bootloader bootloader是处理器上电后执行的第一个程序boot&#xff1a;将硬件引导到正常工作的状态loader&#xff1a;加载操作系统内核到内存的指定位置现在bootloader的功能&#xff1a;增加开机显示、开机音乐、OTA升级、固件验证等功能常见的bootloader&#xff1a…...

以太网——ARP协议工作原理

ARP目录 MAC地址一、ARP是什么?二、ARP工作原理工作机制总结三、ARP报文结构四、ARP缓存MAC地址 我们知道别人的 IP 地址后,就能够向这个 IP 地址所在的主机发送数据包。但是IP 地址只是标识网络层的地址,那么在网络层下方数据链路层是不是也有一个地址能够告诉对方主机自己…...

一文了解AIGC与ChatGPT

一、AIGC简介 1.AIGC基础 (1)AIGC是什么 AIGC是人工智能图形计算的缩写&#xff0c;是一种基于图形处理器&#xff08;GPU&#xff09;的计算技术&#xff0c;可以加速各种计算任务&#xff0c;包括机器学习、深度学习、计算机视觉等。 AIGC是一种基于GPU的计算技术&#x…...

Java利用反射和读取xml实现迷你容器

由于需要框架能实现多态&#xff0c;达到控制反转解耦。所以容器还是需要的&#xff0c;容器的存在可以简化对象获取工作&#xff0c;但是容器也不是万能的。合理使用即可&#xff0c;Spring对我来说太庞大了&#xff0c;用不着&#xff0c;为此给框架写一个迷你版容器。 容器…...

Android12之DRM基本接口实现(二)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…...

普通二维码跳转微信小程序实战

简介 服务端springboot项目,前端基于uniapp的微信小程序,要求扫描二维码之后进入到小程序指定页面,下面记录一下实现过程以及过程中遇到的问题. 实现过程 下面是成功跳转的配置截图: 首先说下二维码规则,这个地方需要填写扫描二维码之后打开的地址,这个地址在我的项目里…...

spring boot 配置加载顺序

由官网的文档得知 https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.external-config Default properties (specified by setting SpringApplication.setDefaultProperties).PropertySource annotations on your Configuration classe…...

基于stm32控制的4G模块在设备模式下通讯

这里的32控制其实和51的控制思路都是一样的&#xff0c;都是先利用一个网络助手将家里的无线网生成局域网&#xff0c;接着通过花生壳软件将局域网变成公共网&#xff0c;最后是利用串口助手&#xff0c;在4G模块的AT指令模式写入命令ATSOCKTCPC,公共网IP地址,公共网端口号&…...

预测宝可梦武力值、分类宝可梦

regression case 股票预测 无人车看到的各种sensor 影像镜头看到马路上的东西作为输入&#xff0c;输出就是方向盘角度等等的操纵策略 scalar 标量 这个是热力图&#xff0c;相当于你的XYZ但是Z用颜色表示了 closed-form solution 闭合解 learning rate事先定好的数值 在lin…...

Linux使用find命令查找文件

find命令 简介语法格式基本参数 参考实例根目录下文件名称的例子指定路径下特定类型的例子指定路径、文件类型特定文件名称的例子指定路径、文件类型特定文件大小的例子指定路径、文件类型 查找近期修改时间的例子指定路径、文件类型 查找空文件或目录的例子指定路径、文件类型…...

安卓使用android studio跨进程通信之AIDL

我写这篇文章不想从最基础的介绍开始,我直接上步骤吧. 1.创建服务端 1.1:创建服务端项目:我的as版本比较高,页面就是这样的 1.2:创建AIDL文件,右键项目,选中aidl aidl名字可以自定义也可以默认 basicTypes是自带的,可以删掉,也可以不删,然后把你自己所需的接口写上去 1.3:创建…...

RabbitMQ基础篇 笔记

RabbitMQ 余额支付 同步调用 一步一步的来&#xff0c;支付业务写完后&#xff0c;如果之后加需求&#xff0c;还需要增加代码&#xff0c;不符合开闭原则。 性能上也有问题&#xff0c;openfeign是同步调用&#xff0c;性能太差。 同步调用耦合太多。 同步的优势是可以立…...

实践小记—静态成员的使用注意(或许由此产生的不知名Bug)

序言 在实际生产过程中&#xff0c;为了便于调用&#xff0c;static修饰的成员会比较容易出现。 如果后期该变量并不会被修改&#xff0c;可以考虑使用。但如果后期需要被修改&#xff0c;使用该变量修饰符则需要慎重考虑。 尤其是在对硬件控制的实际生产中&#xff0c;更需…...

华为OD 身高体重排序(100分)【java】A卷+B卷

华为OD统一考试A卷B卷 新题库说明 你收到的链接上面会标注A卷还是B卷。目前大部分收到的都是B卷。 B卷对应20022部分考题以及新出的题目&#xff0c;A卷对应的是新出的题目。 我将持续更新最新题目 获取更多免费题目可前往夸克网盘下载&#xff0c;请点击以下链接进入&#xff…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

3.3.1_1 检错编码(奇偶校验码)

从这节课开始&#xff0c;我们会探讨数据链路层的差错控制功能&#xff0c;差错控制功能的主要目标是要发现并且解决一个帧内部的位错误&#xff0c;我们需要使用特殊的编码技术去发现帧内部的位错误&#xff0c;当我们发现位错误之后&#xff0c;通常来说有两种解决方案。第一…...

关于 WASM:1. WASM 基础原理

一、WASM 简介 1.1 WebAssembly 是什么&#xff1f; WebAssembly&#xff08;WASM&#xff09; 是一种能在现代浏览器中高效运行的二进制指令格式&#xff0c;它不是传统的编程语言&#xff0c;而是一种 低级字节码格式&#xff0c;可由高级语言&#xff08;如 C、C、Rust&am…...

优选算法第十二讲:队列 + 宽搜 优先级队列

优选算法第十二讲&#xff1a;队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

用机器学习破解新能源领域的“弃风”难题

音乐发烧友深有体会&#xff0c;玩音乐的本质就是玩电网。火电声音偏暖&#xff0c;水电偏冷&#xff0c;风电偏空旷。至于太阳能发的电&#xff0c;则略显朦胧和单薄。 不知你是否有感觉&#xff0c;近两年家里的音响声音越来越冷&#xff0c;听起来越来越单薄&#xff1f; —…...

Python 实现 Web 静态服务器(HTTP 协议)

目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1&#xff09;下载安装包2&#xff09;配置环境变量3&#xff09;安装镜像4&#xff09;node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1&#xff09;使用 http-server2&#xff09;详解 …...

自然语言处理——文本分类

文本分类 传统机器学习方法文本表示向量空间模型 特征选择文档频率互信息信息增益&#xff08;IG&#xff09; 分类器设计贝叶斯理论&#xff1a;线性判别函数 文本分类性能评估P-R曲线ROC曲线 将文本文档或句子分类为预定义的类或类别&#xff0c; 有单标签多类别文本分类和多…...

pgsql:还原数据库后出现重复序列导致“more than one owned sequence found“报错问题的解决

问题&#xff1a; pgsql数据库通过备份数据库文件进行还原时&#xff0c;如果表中有自增序列&#xff0c;还原后可能会出现重复的序列&#xff0c;此时若向表中插入新行时会出现“more than one owned sequence found”的报错提示。 点击菜单“其它”-》“序列”&#xff0c;…...

【汇编逆向系列】六、函数调用包含多个参数之多个整型-参数压栈顺序,rcx,rdx,r8,r9寄存器

从本章节开始&#xff0c;进入到函数有多个参数的情况&#xff0c;前面几个章节中介绍了整型和浮点型使用了不同的寄存器在进行函数传参&#xff0c;ECX是整型的第一个参数的寄存器&#xff0c;那么多个参数的情况下函数如何传参&#xff0c;下面展开介绍参数为整型时候的几种情…...