【设计模式-8】组合模式的树形结构实现原理和代码演示

 组合模式是在处理树形结构时而经常使用的设计模式,树形结构一般是由很多节点对象组合而成的一个整体。我们在开发中经常会碰到这样的结构,比如二叉树、多叉树等,映射到真实生活场景中的书的目录结构,部门的层级结构或者是电脑中的文件目录结构等。

1. 概述

组合模式 是针对树形结构而发展出来的一种设计模式,树形结构是由节点对象组合而成的对象,呈现“个体-整体”的结构,这种模式可以使客户端在操作树形结构的整体或者个体节点对象时,能做出统一的响应,这种整体和个体的概念对客户端来说也是不可见的。

组合模式 可以很好的做到,复杂树形对象的层次结构与客户端解耦的目的,是一种结构性的设计模式。

在这里插入图片描述
 在组合模式中,通常存在三个角色:

  • 抽象构件:一般是接口或者抽象类,声明了子类的方法和属性。子类可以是一个叶子构件 ,也可以是一个容器构件。
  • 叶子构件:实现了抽象构件的接口,位于树形结构中最末端的构件,不能包含其他组件,它需要实现了抽象构件所有的方法。
  • 容器构件:实现了抽象构件的接口,表示容器节点对象,可以存放其他的容器构件对象或者叶子构件对象,在具体业务方法中可以通过递归的方式实现对子节点的遍历。

2. 代码实现

 下面,我们通过一个电脑中文件目录树形结构的例子,来写一个组合模式的Demo案例,具体代码如下:

  • 抽象构件
// 抽象的构件
public abstract class AbstractNode {// 节点名称protected String name;// 构造的文件名称AbstractNode(String name) {this.name = name;}// 添加节点的方法protected abstract void add(AbstractNode abstractNode);// 展示节点的方法protected void show(int lines) {StringBuilder sb = new StringBuilder("|");for (int i = 0; i < lines; i++) {sb.append("—— ");}sb.append(name);System.out.println(sb);}
}
  • 叶子节点 - 文件
// 叶子节点 - 文件
public class File extends AbstractNode {// 构造函数File(String name) {super(name);}@Overrideprotected void add(AbstractNode abstractNode) {// 可以通过抛出异常表示子节点不支持的方法throw new RuntimeException("叶子构件不支持添加新的节点");}@Overrideprotected void show(int lines) {// 调用父类的方法super.show(lines);}
}
  • 容器节点 - 文件夹
// 容器节点 - 文件夹
public class Folder extends AbstractNode{// 文件夹下面的子节点(包含容器节点和叶子节点)private List<AbstractNode> list;// 构造函数默认赋值public Folder(String name) {super(name);this.list = new ArrayList<>();}@Overrideprotected void add(AbstractNode abstractNode) {list.add(abstractNode);}@Overrideprotected void show(int lines) {// 先展示名称super.show(lines);// 节点展示 + 1lines ++;// 子节点的展示for (AbstractNode node : list) {node.show(lines);}}
}
  • 客户端
// 客户端
public class Client {public static void main(String[] args) {// 定义文件夹AbstractNode folder = new Folder("D盘");folder.add(new File("日记.txt"));folder.add(new File("人民的名义.mp4"));// 添加子文件夹AbstractNode sonFolder1 = new Folder("音乐");sonFolder1.add(new File("周杰伦.mp3"));sonFolder1.add(new File("以父之名.mp3"));AbstractNode music = new Folder("张杰");music.add(new File("年轻的战场.mp3"));sonFolder1.add(music);AbstractNode sonFolder2 = new Folder("图片");sonFolder2.add(new File("快看这是美景图.jpeg"));folder.add(sonFolder1);folder.add(sonFolder2);// 文件展示folder.show(0);}
}

 执行的结果如下展示:

在这里插入图片描述

3. UML类图

 根据上面这个代码demo,我们来画一下对应的UML类图吧。

在这里插入图片描述

4. 模式分类

 根据抽象构件中定义的方法,可以分为透明组合模式和安全组合模式两种

  • 透明组合模式:在抽象构建中声明了所有管理成员的方法,包含增加、删除、获取、管理等方法,子类需要全部实现。
  • 安全组合模式:在抽象构件中只定义关于操作的方法,由子类单独生命成员额增加、删除或者管理等方法。

5. 总结

 我们来总结一下,组合模式的主要优点:

  1. 首先组合模式使得客户端可以统一使用组合的结构对象来处理叶子或者容器节点,而不必关系对象的特征,对调用方比较友好。
  2. 组合模式中添加新的容器构件和叶子构件都很方便,无需改动现有类结构,符合开闭原则。

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

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

相关文章

Python多项式回归sklearn

一、理论介绍 多项式回归是一种回归分析的方法&#xff0c;它通过使用多项式函数来拟合数据。与简单线性回归不同&#xff0c;多项式回归可以更灵活地适应数据的曲线特征&#xff0c;因为它可以包含多个特征的高次项。 多项式回归的一般形式为&#xff1a; 在实际应用中&am…

Labview for循环精讲

本文详细介绍Labview中For循环的使用方法&#xff0c;从所有细节让你透彻的看明白For循环是如何使用的&#xff0c;如果有帮助的话记得点赞加关注~ 1. For循环结构 从最简单的地方讲起&#xff0c;一个常用的for循环结构是由for循环结构框图、循环次数、循环计数(i)三部分组成…

Qt事件处理,提升组件类

1.相关说明 1.提升组件QLabel的类&#xff0c;以实现双击功能 2.监控键盘事件&#xff0c;实现上下左右移动 3.鼠标点击获取坐标 2.相关界面 3.相关代码和操作 自定义类TMyLabel&#xff0c;父类为QLabel tmylabel.h #ifndef TMYLABEL_H #define TMYLABEL_H #include <QL…

ARM_Linux的交叉开发以及交叉编译器

目录 为什么要使用交叉开发 为什么要使用交叉编译 交叉编译器的安装 交叉编译器的使用 为什么要使用交叉开发 交叉开发是指在通用的电脑上吧程序编写&#xff0c;编译&#xff0c;调试好&#xff0c;再下载到嵌入式产品中去运行&#xff0c;对于一些简单的程序的话&#xff…

SpringBoot3整合OpenAPI3(Swagger3)

文章目录 一、引入依赖二、使用1. OpenAPIDefinition Info2. Tag3. Operation4. Parameter5. Schema6. ApiResponse swagger2更新到3后&#xff0c;再使用方法上发生了很大的变化&#xff0c;名称也变为OpenAPI3。 官方文档 一、引入依赖 <dependency><groupId>…

如何快速制作动态gif图?制作gif动图就这么简单

静图和动图是图像的两种不同形式。静图是一张静止不动的图片&#xff0c;没有任何动作或变化。而动图则是由一系列静止的图像组成&#xff0c;通过快速连续播放这些图像&#xff0c;可以形成看起来像是有动作的效果。简单来说&#xff0c;静图是静止的&#xff0c;而动图是具有…

网络安全(初版,以后会不断更新)

1.网络安全常识及术语 资产 任何对组织业务具有价值的信息资产&#xff0c;包括计算机硬件、通信设施、IT 环境、数据库、软件、文档 资料、信息服务和人员等。 漏洞 上边提到的“永恒之蓝”就是windows系统的漏洞 漏洞又被称为脆弱性或弱点&#xff08;Weakness&#xff09;&a…

2024年腾讯云优惠券(代金券)领取入口整理汇总

腾讯云作为国内知名的云服务提供商&#xff0c;提供了丰富的云产品&#xff0c;包括云服务器、数据库、存储、CDN等。为了帮助用户降低成本&#xff0c;腾讯云会经常推出各种优惠券活动。本文为大家整理汇总了腾讯云优惠券的领取入口&#xff0c;希望可以助力大家轻松上云&…

RedisConnectionException: Unable to connect to redis.xxx.com:6379

报错 org.springframework.data.redis.connection.PoolException: Could not get a resource from the pool; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to redis.xxx.com:6379at org.springframework.data.redis.connection.lettuc…

nginx虚拟主机

虚拟主机指的就是一个独立的站点配置&#xff0c;是nginx默认支持的一个功能&#xff0c;它能够有自己独立的域名&#xff0c;独立的ip&#xff0c;独立的端口配置&#xff0c;能够配置完整的www服务&#xff0c;列如网站搭建&#xff0c;邮件服务器代理等等。并且nginx支持多虚…

如何在Linux运行RStudio Server并实现Web浏览器远程访问

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” 文章目录 前言1. 安装RStudio Server2. 本地访问3. Linux 安装cpolar4. 配置RStudio server公网访问地址5. …

2024最新软件测试面试题合集

1、前端和后端有什么区别 前端能够从 App 屏幕和浏览器上看到的东西。例如&#xff0c;你所看到的内容、按钮、图片&#xff0c;它们都属于前端。 后端就是那些你在屏幕上看不到但又被用来为前端提供支持的东西。网站的后端涉及搭建服务器、保存和获取数据&#xff0c;以及用于…