当前位置: 首页 > 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…...

PHP和Node.js哪个更爽?

先说结论&#xff0c;rust完胜。 php&#xff1a;laravel&#xff0c;swoole&#xff0c;webman&#xff0c;最开始在苏宁的时候写了几年php&#xff0c;当时觉得php真的是世界上最好的语言&#xff0c;因为当初活在舒适圈里&#xff0c;不愿意跳出来&#xff0c;就好比当初活在…...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)

要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况&#xff0c;可以通过以下几种方式模拟或触发&#xff1a; 1. 增加CPU负载 运行大量计算密集型任务&#xff0c;例如&#xff1a; 使用多线程循环执行复杂计算&#xff08;如数学运算、加密解密等&#xff09;。运行图…...

【HTTP三个基础问题】

面试官您好&#xff01;HTTP是超文本传输协议&#xff0c;是互联网上客户端和服务器之间传输超文本数据&#xff08;比如文字、图片、音频、视频等&#xff09;的核心协议&#xff0c;当前互联网应用最广泛的版本是HTTP1.1&#xff0c;它基于经典的C/S模型&#xff0c;也就是客…...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...

Java面试专项一-准备篇

一、企业简历筛选规则 一般企业的简历筛选流程&#xff1a;首先由HR先筛选一部分简历后&#xff0c;在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如&#xff1a;Boss直聘&#xff08;招聘方平台&#xff09; 直接按照条件进行筛选 例如&#xff1a…...