【设计模式--结构型--组合模式】

设计模式--结构型--组合模式

    • 组合模式
      • 定义
      • 结构
      • 案例
      • 组合模式的分类
      • 优点
      • 使用场景

组合模式

定义

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

结构

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

案例

如下图,我们在访问别的一些管理系统时,经常可以看到类似的菜单。一个菜单可以包含菜单项,也可以包含带有其他菜单项的菜单,因此使用组合模式就很恰当。
需求:针对一个菜单,打印出其包含的所有菜单以及菜单项。

  • 系统管理
    • 菜单管理
      • 编辑菜单
      • 删除菜单
      • 新增菜单
    • 权限配置
      • 权限设置
      • 新增权限
    • 角色管理
      • 新增角色
      • 删除角色
        类图:
        在这里插入图片描述
/*** 菜单组件  抽象根节点*/
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();
}
/*** 菜单类  树枝节点*/
public class Menu extends MenuComponent {// 菜单可以有多个子菜单或者子菜单项private List<MenuComponent> menuComponentList = new ArrayList<>();// 构造方法public Menu(String name, int level) {this.name = name;this.level = level;}@Overridepublic void add(MenuComponent menuComponent) {menuComponentList.add(menuComponent);}@Overridepublic void remove(MenuComponent menuComponent) {menuComponentList.remove(menuComponent);}@Overridepublic MenuComponent getChild(int index) {return menuComponentList.get(index);}@Overridepublic void print() {// 打印菜单名称for (int i = 0; i < level; i++) {System.out.print("—");}System.out.println(name);// 打印子菜单或子菜单项名称for (MenuComponent menuComponent : menuComponentList) {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 Test01 {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));MenuComponent menu2 = new Menu("权限管理", 2);menu2.add(new MenuItem("权限设置", 3));menu2.add(new MenuItem("新增权限", 3));MenuComponent menu3 = new Menu("角色管理", 2);menu2.add(new MenuItem("新增角色", 3));menu2.add(new MenuItem("删除角色", 3));// 创建一级菜单MenuComponent component = new Menu("系统管理", 1);component.add(menu1);component.add(menu2);component.add(menu3);// 打印菜单名称(如果有子菜单一起打印)component.print();}
}

在这里插入图片描述

组合模式的分类

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

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

优点

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

使用场景

出现树型结构的地方都可以使用组合模式

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

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

相关文章

新增模板中心和系统设置模块,支持飞书平台对接,DataEase开源数据可视化分析平台v2.1.0发布

这一版本的功能升级包括&#xff1a;新增模板中心&#xff0c;用户可以通过模板中心的模板快速创建仪表板和数据大屏&#xff1b;新增“系统设置”功能模块&#xff0c;该模块包含系统参数、认证设置、嵌入式管理、平台对接四个子模块。在“系统参数”子模块中&#xff0c;用户…

代码上传的gitee平台

1.首先我们访问工作台 - Gitee.com进行注册和登录 2.我们创建一个仓库&#xff1a; 3.在本地创建我们的项目 在这文件夹里面我们打开git bush,执行 一下操作&#xff1a; git init &#xff1a;初始化仓库 git status&#xff1a;检查状态 git add . &#xff1a;将当前文件…

ubuntu 命令行安装 conda

安装包地址&#xff1a; Index of / 找到对应的版本&#xff0c;右键点复制链接 wget https://repo.anaconda.com/archive/Anaconda3-2023.09-0-Linux-x86_64.shbash Anaconda3-2023.09-0-Linux-x86_64.sh https://linzhji.blog.csdn.net/article/details/126530244

BERT大模型:英语NLP的里程碑

BERT的诞生与重要性 BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;大模型标志着自然语言处理&#xff08;NLP&#xff09;领域的一个重要转折点。作为首个利用掩蔽语言模型&#xff08;MLM&#xff09;在英语语言上进行预训练的模型&…

Keepalived+Nginx实现高可用(上)

一、背景与简介 为了服务的高可用性&#xff0c;避免单点故障问题&#xff0c;通常我们使用"冗余设计思想"进行架构设计。冗余设计思想&#xff0c;本质就是将同一个应用或者服务放置在多台不同的服务器上[鸡蛋不放在同一个篮子里]&#xff0c;这样减少整体服务宕机的…

ACWing week 3(C语言) 725.完全数

一个整数&#xff0c;除了本身以外的其他所有约数的和如果等于该数&#xff0c;那么我们就称这个整数为完全数。 例如&#xff0c;66 就是一个完全数&#xff0c;因为它的除了本身以外的其他约数的和为 1236 现在&#xff0c;给定你 N 个整数&#xff0c;请你依次判断这些数是…

ESP32网络开发实例-搭建ESP32固件远程升级服务器

搭建ESP32固件远程升级服务器 文章目录 搭建ESP32固件远程升级服务器1、ESP32设备自动升级流程2、软件准备3、硬件准备4、代码实现4.1 固件升级服务器代码实现4.2 基础固件代码4.3 新固件代码实现我们在前面的文章中,已经实现了OTA方式升级固件的两种方式:在Arduino IDE 中升…

数据结构与算法-动态规划-机器人达到指定位置方法数

机器人达到指定位置方法数 来自左程云老师书中的一道题 【题目】 假设有排成一行的 N 个位置&#xff0c;记为 1~N&#xff0c;N 一定大于或等于 2。开始时机器人在其中的 M 位置上&#xff08;M 一定是 1&#xff5e;N 中的一个&#xff09;&#xff0c;机器人可以往左走或…

基于大语言模型的复杂任务认知推理算法CogTree

近日&#xff0c;阿里云人工智能平台PAI与华东师范大学张伟教授团队合作在自然语言处理顶级会议EMNLP2023上发表了基于认知理论所衍生的CogTree认知树生成式语言模型。通过两个系统&#xff1a;直觉系统和反思系统来模仿人类产生认知的过程。直觉系统负责产生原始问题的多个分解…

10 # 类:继承和成员修饰符

类的基本实现 类的成员属性都是实例属性&#xff0c;而不是原型属性&#xff0c;类的成员方法都是原型方法。 class Dog {constructor(name: string) {this.name name;}name: string;run() {} }console.log(Dog.prototype); let dog new Dog("wangwang"); consol…

知识笔记(五十四)———mysql比较varchar值大小_Mysql varchar大小长度问题

1、限制规则 字段的限制在字段定义的时候有以下规则&#xff1a; a) 存储限制 varchar 字段是将实际内容单独存储在聚簇索引之外&#xff0c;内容开头用1到2个字节表示实际长度(长度超过255时需要2个字节)&#xff0c;因此最大长度不能超过65535。 b) 编码长度限制 字符类…

低功耗模式的通用 MCU ACM32F0X0 系列,具有高整合度、高抗干扰、 高可靠性的特点

ACM32F0X0 系列是一款支持多种低功耗模式的通用 MCU。集成 12 位 1.6 Msps 高精度 ADC 以及比 较器、运放、触控按键控制器、段式 LCD 控制器&#xff0c;内置高性能定时器、多路 UART、LPUART、SPI、I2C 等丰富的通讯外设&#xff0c;内建 AES、TRNG 等信息安全模块&#xff0…

kubeadm搭建单master多node的k8s集群--小白文,图文教程

参考文献 K8S基础知识与集群搭建 kubeadm搭建单master多node的k8s集群—主要参考这个博客&#xff0c;但是有坑&#xff0c;故贴出我自己的过程&#xff0c;坑会少很多 注意&#xff1a; 集群配置是&#xff1a;一台master&#xff1a;zabbixagent-k8smaster&#xff0c;两台…

C++类和对象——(10)综合示例

一、示例对象数组&#xff1a; #include<iostream> using namespace std;class Point{private:int x,y;public:Point(int px0,int py0){xpx;ypy;}void init(int px0,int py0){xpx;ypy;}void print(){cout<<"("<<x<<","<<y…

FFmpeg的AVInputFormat

文章目录 结构体定义操作函数支持的AVOutputFormat 通过上面的分析&#xff0c;基本可以看到ffmpeg的套路了&#xff0c;首先一个context上下文&#xff0c;上下文里面一个priv_data 指针&#xff0c;然后再插件结构体中有一个priv_data_size&#xff0c;然后回调函数。 结构体…

JVM-GC调优-字节码篇-01

笔记来源&#xff1a;JVM 注意&#xff1a;实在想学习可以看一下&#xff0c;让自己更加了解JVM&#xff0c;看起来可能会枯燥。 JVM-概述 1、你的问题 1.1你被JVM伤害过吗&#xff1f; 你是否也遇到过这些问题&#xff1f; 运行着的线上系统突然卡死&#xff0c;系统无法访…

Flink SQL: 高效解析 Kafka 数据并存储为 Parquet 至 HDFS

目录 总体流程介绍 1. 从 Kafka 读取数据 2. 使用 UDF 进行数据解析 3. 将

HTML中如何设置音频和视频?

文章目录 &#x1f50a;嵌入音频&#x1f39e;️嵌入视频 &#x1f50a;嵌入音频 HTML 元素用于在文档中嵌入音频内容。 元素可以包含一个或多个音频资源&#xff0c; 这些音频资源可以使用 src 属性或者 元素来进行描述&#xff1a;浏览器将会选择最合适的一个来使用。也可以使…

Centos7云服务器上安装cobalt_strike_4.7。附cobalt_strike_4.7安装包

环境这里是阿里的一台Centos7系统。 开始安装之前首先要确保自己安装了java11及以上环境。 安装java11步骤&#xff1a; sudo yum update sudo yum install java-11-openjdk-devel把服务器端&#xff08;CS工具分服务器端和客户端&#xff09;的CS安装到服务器上后给目录下的…

Mongoose 对象文档模型库

一、介绍 Mongoose是一个对象文档模型库&#xff0c;官网&#xff1a;http://www.mongoosejs.net/ 二、作用 方便使用代码操作Mongodb数据库 三、使用流程 //1. 安装 mongoose //2. 导入 mongoose const mongoose require(mongoose); //3. 连接数据库 mongoose.connect(m…