【设计模式】组合模式

文章目录

  • 前言
  • 一、组合模式
    • 1.案例
    • 2.组合模式分类
    • 3.优点
    • 4.使用场景
  • 总结


前言

【设计模式】组合模式


一、组合模式

在这里插入图片描述

​ 对于这个图片肯定会非常熟悉,上图我们可以看做是一个文件系统,对于这样的结构我们称之为树形结构。在树形结构中可以通过调用某个方法来遍历整个树,当我们找到某个叶子节点后,就可以对叶子节点进行相关的操作。可以将这颗树理解成一个大的容器,容器里面包含很多的成员对象,这些成员对象即可是容器对象也可以是叶子对象。但是由于容器对象和叶子对象在功能上面的区别,使得我们在使用的过程中必须要区分容器对象和叶子对象,但是这样就会给客户带来不必要的麻烦,作为客户而已,它始终希望能够一致的对待容器对象和叶子对象。
组合模式:

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

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

  • 抽象根节点(Component):定义系统各层次对象的共有方法和属性,可以预先定义一些默认行为和属性。
  • 树枝节点(Composite):定义树枝节点的行为,存储子节点,组合树枝节点和叶子节点形成一个树形结构。
  • 叶子节点(Leaf):叶子节点对象,其下再无分支,是系统层次遍历的最小单位。

1.案例

【例】软件菜单

如下图,我们在访问别的一些管理系统时,经常可以看到类似的菜单。一个菜单可以包含菜单项(菜单项是指不再包含其他内容的菜单条目),也可以包含带有其他菜单项的菜单,因此使用组合模式描述菜单就很恰当,我们的需求是针对一个菜单,打印出其包含的所有菜单以及菜单项的名称。

在这里插入图片描述
要实现该案例,我们先画出类图:
在这里插入图片描述
代码实现:
不管是菜单还是菜单项,都应该继承自统一的接口,这里姑且将这个统一的接口称为菜单组件。

/*** @Version: 1.0.0* @Author: Dragon_王* @ClassName: MenuComponent* @Description: 菜单组件,属于抽象根节点* @Date: 2023/12/25 10:47*/
public abstract class MenuComponent {// 菜单组件的名称protected String name;// 菜单组件的层级protected int level;// 添加子菜单public void add(MenuComponent menuComponent) {throw new UnsupportedOperationException();}// 移除子菜单public void remove(MenuComponent menuComponent) {throw new UnsupportedOperationException();}// 获取指定的子菜单public MenuComponent getChild(int index) {throw new UnsupportedOperationException();}// 获取菜单或菜单项的名称public String getName() {return name;}// 打印菜单名称的方法(包含子菜单和子菜单项)public abstract void print();}

这里的MenuComponent定义为抽象类,因为有一些共有的属性和行为要在该类中实现,Menu和MenuItem类就可以只覆盖自己感兴趣的方法,而不用搭理不需要或者不感兴趣的方法,举例来说,Menu类可以包含子菜单,因此需要覆盖add()、remove()、getChild()方法,但是MenuItem就不应该有这些方法。这里给出的默认实现是抛出异常,你也可以根据自己的需要改写默认实现。

/*** @Version: 1.0.0* @Author: Dragon_王* @ClassName: Menu* @Description: 菜单类,属于树枝节点* @Date: 2023/12/25 10:55*/
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 MenuComponent getChild(int index) {return menuComponents.get(index);}@Overridepublic void print() {for (int i = 0;i < level;i++){System.out.print("--");}System.out.println(name);menuComponents.forEach(menuComponent -> menuComponent.print());}
}

Menu类已经实现了除了getName方法的其他所有方法,因为Menu类具有添加菜单,移除菜单和获取子菜单的功能。

/*** @Version: 1.0.0* @Author: Dragon_王* @ClassName: MenuItem* @Description: 菜单项类,属于叶子节点* @Date: 2023/12/25 11:02*/
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);}
}

MenuItem是菜单项,不能再有子菜单,所以添加菜单,移除菜单和获取子菜单的功能并不能实现。

/*** @Version: 1.0.0* @Author: Dragon_王* @ClassName: Client* @Description: 测试类* @Date: 2023/12/25 11:04*/
public class Client {public static void main(String[] args) {MenuComponent menu1 =new Menu("菜单管理",2);menu1.add(new MenuItem("页面访问",3));menu1.add(new MenuItem("展开菜单",3));menu1.add(new MenuItem("编辑菜单",3));menu1.add(new MenuItem("删除菜单",3));menu1.add(new MenuItem("新增菜单",3));MenuComponent menu2 = new Menu("权限管理",2);menu2.add(new MenuItem("页面访问",3));menu2.add(new MenuItem("提交保存",3));MenuComponent menu3 = new Menu("角色管理",2);menu3.add(new MenuItem("页面访问",3));menu3.add(new MenuItem("新增角色",3));menu3.add(new MenuItem("修改角色",3));// 创建一级菜单MenuComponent component = new Menu("系统管理",1);component.add(menu1);component.add(menu2);component.add(menu3);component.print();}
}

在这里插入图片描述

2.组合模式分类

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

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

在这里插入图片描述

3.优点

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

4.使用场景

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


总结

以上就是组合模式的讲解。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

一款超酷的一体化网站测试工具:Web-Check

Web-Check 是一款功能强大的一体化工具&#xff0c;用于发现网站/主机的相关信息。用于检查网页的工具&#xff0c;用于确保网页的正确性和可访问性。它可以帮助开发人员和网站管理员检测网页中的错误和问题&#xff0c;并提供修复建议。 它只需要输入一个网站就可以查看一个网…

数据库系统原理例题之——SQL 与关系数据库基本操作

SQL 与关系数据库基本操作 第四章 SQL 与关系数据库基本操作【例题】一 、单选题二 、填空题三 、简答题四 、设计题 【答案&解析】一、单选题二、填空题三、简答题四、设计题 【延伸知识点】【延伸知识点答案&解析】 第四章 SQL 与关系数据库基本操作 【例题】 一 、…

【23.12.30期--Spring篇】Spring的AOP介绍(详解)

Spring的AOP介绍 ✔️简述✔️扩展知识✔️AOP是如何实现的 ✔️简述 AOP(Aspect-Oriented Programming)&#xff0c;即面向切面编程&#xff0c;用人话说就是把公共的逻辑抽出来&#xff0c;让开发者可以更专注于业务逻辑开发。 和IOC-样&#xff0c;AOP也指的是一种思想。AOP…

字符串函数的实现以及大小写转换、字符统计等------(C每日一编程)

--基本算法&#xff1a; --字符串求长度、拷贝、比较、连接 --大小写转换、字符统计 -其他&#xff1a; --判断回文、逆序、删字符、字符定位 --输入&#xff08;gets&#xff09;、输出&#xff08;puts&#xff09; 正文解读&#xff1a; 大小写转换&#xff1a;就是加减32…

Shell三剑客:awk(awk编辑编程)六

一、AWK 的函数前言 awk的函数有许多&#xff0c;除了系统自带的内建函数还有就是用户自定义的函数。 二、AWK 常用的函数 rand() # 返回0 和1 之间一个随机数srand() # 生成随机数种子int() # 取整数length([s]) # 返回指定字符串的长度sub(r,s,[t]) # 对t字符串进行搜索&am…

【C++杂货铺】C++11新特性——lambda

文章目录 一、C98中的排序二、先来看看 lambda 表达式长什么样三、lambda表达式语法3.1 捕捉列表的使用细节 四、lambda 的底层原理五、结语 一、C98中的排序 在 C98 中&#xff0c;如果要对一个数据集合中的元素进行排序&#xff0c;可以使用 std::sort 方法&#xff0c;下面…

Spring Boot 基于Redisson实现注解式分布式锁

依赖版本 JDK 17 Spring Boot 3.2.0 Redisson 3.25.0 源码地址&#xff1a;Gitee 导入依赖 <properties><redisson.version>3.25.0</redisson.version> </properties><dependencies><dependency><groupId>org.projectlombok</…

为什么网络安全行业那么缺人才,但招聘岗位却没那么多?

文章目录 一、学校的偏向于学术二、学的东西太基础三、不上班行不行 为什么网络安全的人才缺口那么大&#xff0c;但是大学毕业能找到网安工作的人却很少&#xff0c;就连招聘都没有其他岗位多&#xff1f; 明明央视都说了网络安全的人才缺口还有300多万&#xff0c;现在找不…

Python 下载与安装

1、下载 打开Python官网&#xff1a;Welcome to Python.org 点击下图所示的【Downloads】按钮进入下载页面。 ​ 进入下载页面后下拉至下图位置&#xff0c;选择版本&#xff0c;点击下载按钮下载。 页面会跳转至下一页下载页面&#xff0c;下拉到下图位置&#xff0c;选择…

18 UVM Scoreboard

UVM scoreboard是一个检查DUT功能的组件。它用analysis export从monitor接受transaction事务以进行检查。 uvm_scoreboard class declaration: virtual class uvm_scoreboard extends uvm_component User-defined scoreboard class declaration: 用户定义的scoreboard是从 u…

非对称加密与对称加密的区别是什么?

在数据通信中&#xff0c;加密技术是防止数据被未授权的人访问的关键措施之一。而对称加密和非对称加密是两种最常见的加密技术&#xff0c;它们被广泛应用于数据安全领域&#xff0c;并且可以组合起来以达到更好的加密效果。本文将探讨这两种技术的区别&#xff0c;以及它们在…

OpenHarmony 快速集成轻量级存储(dataPreferences)工具类

OpenHarmony中也有类似于Android的SharedPreferences的轻量级存储&#xff0c;名字叫dataPreferences&#xff0c;这里省略介绍&#xff0c;直接放工具类 一.初始化 首先在EntryAbility中对dataPreferences进行初始化操作&#xff0c;初始化的代码如下&#xff1a; import d…

基于Java+SpringMvc+Vue求职招聘系统详细设计实现

基于JavaSpringMvcVue求职招聘系统详细设计实现 &#x1f345; 作者主页 专业程序开发 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; 文章目录 基于JavaSpringMvcVue求职招聘系统详细设计实现一、前言介…

Nacos注册及使用

一、简介 Nacos是阿里云开源的一个服务发现、配置管理和服务鉴权平台&#xff0c;它提供了一种更简单、更便捷、更开放的方式来管理服务&#xff0c;帮助开发者快速实现服务的发现、配置的管理、服务的鉴权等功能。Nacos可以帮助开发者轻松管理微服务应用中的服务提供者、服务…

啊?这也算事务?!

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 学习必须往深处挖&…

GBASE南大通用-GBase 8s数据库日志模式及切换

一、 GBase 8s数据库共有以下 4 种日志模式&#xff1a;无日志模式、缓冲日志模式、无缓冲日志模式、ANSI 模式。详细介绍如下&#xff1a; 1、无日志模式&#xff08;Non logging&#xff09;&#xff1a; 采用无日志模式时&#xff0c;所有 DML 操作都不会被记录到日志中&…

关于表格太大了jupyter无法单次处理的问题

记录下自己的心路历程…耗时耗精力 我用的数据库单个表格就很大&#xff0c;一个表格有30多G&#xff0c;jupyter无法处理这么大的表格&#xff0c;会直接把电脑的进程全部结束掉&#xff0c;结束掉要是能运行成功倒也行啊&#xff0c;然鹅…给我报错说处理不了&#xff0c;罢工…

代码随想录刷题 | Day1

今日学习目标 一、基础 数组 array类 模板类vector 数组是存放在连续内存空间上的相同类型数据的集合。 数组可以方便的通过下标索引的方式获取到下标下对应的数据。 需要两点注意的是 数组下标都是从0开始的。 数组内存空间的地址是连续的 而且大家如果使用C的话&…

儿童学python语言能做什么,儿童学python哪个机构好

这篇文章主要介绍了儿童学python哪个线上机构好&#xff0c;具有一定借鉴价值&#xff0c;需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获&#xff0c;下面让小编带着大家一起了解一下。 少儿编程python 文章目录 前言 CSP-J与CSP-S少儿编程证书含金量排名&#xff0…

linux实用技巧:ubuntu18.04安装samba服务器实现局域网文件共享

Ubuntu安装配置Samba服务与Win10共享文件 Chapter1 Ubuntu18.04安装配置Samba服务与Win10共享文件一、什么是Samba二、安装Samba1、查看是否有安装samba2、安装samba 三、配置Samba服务1、创建共享目录&#xff08;以samba_workspaces为例&#xff09;2、为samba设置登录用户3、…