结构型-组合模式(Composite Pattern)
什么是组合模式
又名部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。
结构
- 抽象根节点(Component):定义系统各层次对象的共有方法和属性,可以预先定义一些默认行为和属性。
- 树枝节点(Composite):定义树枝节点的行为,存储子节点,组合树枝节点和叶子节点形成一个树形结构。
- 叶子节点(Leaf):叶子节点对象,其下再无分支,是系统层次遍历的最小单位。
UML类图

代码理解

package com.babs.pattern.comprise;/*** 菜单组件 抽象根节点** @author TYT* @version 1.0.0*/
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();
}package com.babs.pattern.comprise;import java.util.ArrayList;
import java.util.List;/*** 菜单类 树枝节点** @author TYT* @version 1.0.0*/
public class Menu extends MenuComponent {// 菜单可以有多个子菜单或者子菜单项private List<MenuComponent> menuComponentList = new ArrayList<MenuComponent>();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);// 打印子菜单名称和子菜单名称menuComponentList.forEach(MenuComponent::print);}
}package com.babs.pattern.comprise;/*** 菜单项 叶子节点** @author TYT* @version 1.0.0*/
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);}
}package com.babs.pattern.comprise;/*** 客户端测试** @author TYT* @version 1.0.0*/
public class Client {public static void main(String[] args) {MenuComponent menu1 = new Menu("菜单管理", 2);menu1.add(new MenuItem("menu1子菜单1", 3));menu1.add(new MenuItem("menu1子菜单2", 3));menu1.add(new MenuItem("menu1子菜单3", 3));MenuComponent menu2 = new Menu("权限管理", 2);menu2.add(new MenuItem("menu2子菜单1", 3));menu2.add(new MenuItem("menu2子菜单2", 3));menu2.add(new MenuItem("menu2子菜单3", 3));MenuComponent menu3 = new Menu("角色管理", 2);menu3.add(new MenuItem("menu3子菜单1", 3));menu3.add(new MenuItem("menu3子菜单2", 3));menu3.add(new MenuItem("menu3子菜单3", 3));MenuComponent component = new Menu("系统管理", 1);component.add(menu1);component.add(menu2);component.add(menu3);component.print();}
}
组合模式的分类
在使用组合模式时,根据抽象构件类的定义形式,我们可将组合模式分为透明组合模式和安全组合模式两种形式。
- 透明组合模式
透明组合模式中,抽象根节点角色中声明了所有用于管理成员对象的方法,比如在示例中 MenuComponent 声明了 add、remove 、getChild 方法,这样做的好处是确保所有的构件类都有相同的接口。透明组合模式也是组合模式的标准形式。透明组合模式的缺点是不够安全,因为叶子对象和容器对象在本质上是有区别的,叶子对象不可能有下一个层次的对象,即不可能包含成员对象,因此为其提供 add()、remove() 等方法是没有意义的,这在编译阶段不会出错,但在运行阶段如果调用这些方法可能会出错(如果没有提供相应的错误处理代码)
- 安全组合模式
在安全组合模式中,在抽象构件角色中没有声明任何用于管理成员对象的方法,而是在树枝节点 Menu 类中声明并实现这些方法。安全组合模式的缺点是不够透明,因为叶子构件和容器构件具有不同的方法,且容器构件中那些用于管理成员对象的方法没有在抽象构件类中定义,因此客户端不能完全针对抽象编程,必须有区别地对待叶子构件和容器构件。
优点
- 一致性:客户可以一致地对待个体对象和对象组合。
- 灵活性:可以很容易地增加新的组合类型,符合开闭原则。
- 简化高层代码:因为组合模式隐藏了对象之间的关系,所以高层代码不需要关心是单个对象还是组合对象。
缺点
- 可能会导致设计复杂化:如果系统中存在大量不同类型的组件,那么维护这个模式可能会变得相当复杂。
- 不容易限制容器中的构件:不容易用继承的方法来增加构件的新功能
使用场景
- 当程序结构有类似树一样的层级关系时,例如文件系统、视图树、公司组织架构等。
- 当需要以统一的方式操作单个对象和由这些对象组成的组合对象时。
相关文章:
结构型-组合模式(Composite Pattern)
什么是组合模式 又名部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。 结构 抽象根节点(Co…...
【知识堂】大数据
一、大数据的基本概念 什么是大数据? 大数据(Big Data)是指无法通过传统工具和方法在合理时间内处理的海量数据集合。其关键特征是4V,即数据量大(Volume)、数据种类多(Variety)、处…...
力扣C语言刷题记录(三)搜索插入位置
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 示例 1: 输入: nums [1,3,5,6], target 5 输出: 2示例 2: 输入:…...
在Node.js局域网调试https的Vue项目
需求: 最近在测试在网页端(HTML5)调用移动设备的定位等权限功能,发现某些功能是必须保证域名在https下的否则会出现不正常现象。 解决: 1.在线生成和证书 访问:CSR文件生成工具-中国数字证书CHINASSL …...
3.5 认识决策树
3.5 认识决策树 3.5.1 认识决策树 如何高效的进行决策? 特征的先后顺序 3.5.2 决策树分类原理详解 已知有四个特征,预测 是否贷款给某个人。 先看房子,再看工作,是否贷款。 年龄,信贷情况,工作&#…...
股市复盘笔记
复盘是股市投资中非常重要的一个环节,它指的是投资者在股市收盘后,对当天的市场走势、个股表现以及自己的交易行为进行回顾和总结,以便更好地指导未来的投资决策。以下是对复盘的详细解释: 一、复盘的目的 总结市场走势ÿ…...
Canal 深入解析:从原理到实践的全面解读
Canal 深入解析:从原理到实践的全面解读 官网:https://github.com/alibaba/canal Canal 是阿里巴巴开源的一款分布式增量数据同步工具,广泛应用于数据同步、实时数据处理和数据库的增量备份等场景。它可以通过监听 MySQL 数据库的 binlog&am…...
SQL SERVER 2016 AlwaysOn 无域集群+负载均衡搭建与简测
之前和很多群友聊天发现对2016的无域和负载均衡满心期待,毕竟可以简单搭建而且可以不适用第三方负载均衡器,SQL自己可以负载了。windows2016已经可以下载使用了,那么这回终于可以揭开令人憧憬向往的AlwaysOn2016 负载均衡集群的神秘面纱了。 …...
解决 Maven 部署中的 Artifact 覆盖问题:实战经验分享20241204
🛠️ 解决 Maven 部署中的 Artifact 覆盖问题:实战经验分享 📌 引言 在软件开发过程中,持续集成和持续部署(CI/CD)是提高开发效率和代码质量的关键手段。Hudson 和 Maven 是两种广泛使用的工具࿰…...
【开源免费】基于SpringBoot+Vue.JS中小型医院网站(JAVA毕业设计)
博主说明:本文项目编号 T 078 ,文末自助获取源码 \color{red}{T078,文末自助获取源码} T078,文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析…...
Linux CentOS
阿里云开源镜像下载链接 https://mirrors.aliyun.com/centos/7/isos/x86_64/ VMware 安装 CentOS7 自定义 下一步 选择稍后安装操作系统 选择 输入 查看物理机CPU内核数量 CtrlShiftEsc 总数不超过物理机内核数量 推荐内存 自选 推荐 推荐 默认 拆分成多个 默认 自定义硬件…...
Android SurfaceFlinger layer层级
壁纸作为显示的最底层窗口它是怎么显示的 1. SurfaceFlinger layer层级 锁屏状态dump SurfaceFlinger ,adb shell dumpsys SurfaceFlinger Display 0 (active) HWC layers: -----------------------------------------------------------------------------------…...
spark-sql配置教程
1.前期准备 (1)首先要把hadoop集群,hive和spark等配置好 hadoop集群,hive的配置可以看看这个博主写的博客 大数据_蓝净云的博客-CSDN博客 或者看看黑马程序员的视频 黑马程序员大数据入门到实战教程,大数据开发必…...
生成表格pdf格式
1. 添加依赖 <dependency><groupId>com.itextpdf</groupId><artifactId>kernel</artifactId><version>7.2.5</version></dependency><dependency><groupId>com.itextpdf</groupId><artifactId>layout…...
C++ 游戏开发的前沿趋势:从光线追踪到人工智能的全新挑战
随着游戏行业的快速发展,技术的不断进步为游戏开发带来了前所未有的机遇和挑战。从逼真的光影效果到复杂的物理模拟,再到智能化的非玩家角色(NPC)行为和玩家交互,现代游戏的技术需求已经超越了传统的图形渲染与场景搭建…...
微信小程序3-显标记信息和弹框
感谢阅读,初学小白,有错指正。 一、实现功能: 在地图上添加标记点后,标记点是可以携带以下基础信息的,如标题、id、经纬度等。但是对于开发来说,这些信息还不足够,而且还要做到点击标记点时&a…...
EasyNVR中HTTP-FLV协议无法播放怎么解决?
在科技日新月异的今天,摄像头作为公共安全领域的重要一环,其技术的不断提升正显著地改变着社会的安全格局。从最初的简单监控到如今的高清智能分析,我们可以对特定区域进行实时监控和记录,为社会的安全稳定提供了强有力的保障。 问…...
spring cloud之ribbon复习回顾
其实在项目中直接使用ribbon时不多,大多是使用feign的,其实feign底层也是通过ribbon构建的,主要记忆一下计算规则,ribbon的源码还是很不错的,还是值得学习的。 1、添加pom <dependency><groupId>org.spr…...
RFT 强化微调
OpenAI在今天发布的新技术,RFT结合了SFT和RL的优化算法,与传统的监督微调不同,强化微调旨在通过任务训练让模型掌握复杂推理能力,而不仅仅是“记住答案”。 什么是强化微调 强化微调是通过高质量任务数据和参考答案优化大语言模型…...
SpringBoot教程(三十二) SpringBoot集成Skywalking链路跟踪
SpringBoot教程(三十二) | SpringBoot集成Skywalking链路跟踪 一、Skywalking是什么?二、Skywalking与JDK版本的对应关系三、Skywalking下载四、Skywalking 数据存储五、Skywalking 的启动六、部署探针 前提: Agents 8.9.0 放入 …...
【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...
大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...
【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...
vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...
Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)
引言 在人工智能飞速发展的今天,大语言模型(Large Language Models, LLMs)已成为技术领域的焦点。从智能写作到代码生成,LLM 的应用场景不断扩展,深刻改变了我们的工作和生活方式。然而,理解这些模型的内部…...
提升移动端网页调试效率:WebDebugX 与常见工具组合实践
在日常移动端开发中,网页调试始终是一个高频但又极具挑战的环节。尤其在面对 iOS 与 Android 的混合技术栈、各种设备差异化行为时,开发者迫切需要一套高效、可靠且跨平台的调试方案。过去,我们或多或少使用过 Chrome DevTools、Remote Debug…...
