【设计模式】十、组合模式
文章目录
- 案例
- 组合模式
- 基本介绍
- 类图
- 代码
- 组合模式在 JDK 集合的源码分析
- 组合模式的注意事项和细节
案例
编写程序展示一个学校院系结构:需求是这样,要在一个页面中展示出学校的院系组成,一个学校有多个学院,一个学院有多个系。如图:
传统方案解决学校院系展示(类图)

传统方案解决学校院系展示存在的问题分析:
- 将学院看做是学校的子类,系是学院的子类,这样实际上是站在组织大小来进行分层次的
- 实际上我们的要求是 :在一个页面中展示出学校的院系组成,一个学校有多个学院,一个学院有多个系, 因此这种方案,不能很好实现的管理的操作,比如对学院、系的添加,删除,遍历等
- 解决方案:把学校、院、系都看做是组织结构,他们之间没有继承的关系,而是一个树形结构,可以更好的实现管理操作。 => 组合模式
组合模式
基本介绍
- 组合模式(Composite Pattern),又叫部分整体模式,它创建了对象组的树形结构,将对象组合成树状结构以表示“整体-部分”的层次关系。
- 组合模式依据树形结构来组合对象,用来表示部分以及整体层次。
- 这种类型的设计模式属于结构型模式。
- 组合模式使得用户对单个对象和组合对象的访问具有一致性,即:组合能让客户以一致的方式处理个别对象以及组合对象
类图
对原理结构图的说明-即(组合模式的角色及职责):
- Component :这是组合中对象声明接口,在适当情况下,实现所有类共有的接口默认行为,用于访问和管理Component 子部件, Component 可以是抽象类或者接口
- Leaf : 在组合中表示叶子节点,叶子节点没有子节点
- Composite :非叶子节点, 用于存储子部件, 在 Component接口中实现 子部件的相关操作,比如增加(add),删除
代码
public abstract class OrganizationComponent {private String name; // 名字private String des; // 说明protected void add(OrganizationComponent organizationComponent) {//默认实现throw new UnsupportedOperationException();}protected void remove(OrganizationComponent organizationComponent) {//默认实现throw new UnsupportedOperationException();}//构造器public OrganizationComponent(String name, String des) {super();this.name = name;this.des = des;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getDes() {return des;}public void setDes(String des) {this.des = des;}//方法print, 做成抽象的, 子类都需要实现protected abstract void print();}
//University 就是 Composite , 可以管理College
public class University extends OrganizationComponent {List<OrganizationComponent> organizationComponents = new ArrayList<OrganizationComponent>();// 构造器public University(String name, String des) {super(name, des);// TODO Auto-generated constructor stub}// 重写add@Overrideprotected void add(OrganizationComponent organizationComponent) {// TODO Auto-generated method stuborganizationComponents.add(organizationComponent);}// 重写remove@Overrideprotected void remove(OrganizationComponent organizationComponent) {// TODO Auto-generated method stuborganizationComponents.remove(organizationComponent);}@Overridepublic String getName() {// TODO Auto-generated method stubreturn super.getName();}@Overridepublic String getDes() {// TODO Auto-generated method stubreturn super.getDes();}// print方法,就是输出University 包含的学院@Overrideprotected void print() {// TODO Auto-generated method stubSystem.out.println("--------------" + getName() + "--------------");//遍历 organizationComponents for (OrganizationComponent organizationComponent : organizationComponents) {organizationComponent.print();}}}
public class College extends OrganizationComponent {//List 中 存放的DepartmentList<OrganizationComponent> organizationComponents = new ArrayList<OrganizationComponent>();// 构造器public College(String name, String des) {super(name, des);// TODO Auto-generated constructor stub}// 重写add@Overrideprotected void add(OrganizationComponent organizationComponent) {// TODO Auto-generated method stub// 将来实际业务中,Colleage 的 add 和 University add 不一定完全一样organizationComponents.add(organizationComponent);}// 重写remove@Overrideprotected void remove(OrganizationComponent organizationComponent) {// TODO Auto-generated method stuborganizationComponents.remove(organizationComponent);}@Overridepublic String getName() {// TODO Auto-generated method stubreturn super.getName();}@Overridepublic String getDes() {// TODO Auto-generated method stubreturn super.getDes();}// print方法,就是输出University 包含的学院@Overrideprotected void print() {// TODO Auto-generated method stubSystem.out.println("--------------" + getName() + "--------------");//遍历 organizationComponents //递归for (OrganizationComponent organizationComponent : organizationComponents) {organizationComponent.print();}}}
public class Department extends OrganizationComponent {//没有集合public Department(String name, String des) {super(name, des);// TODO Auto-generated constructor stub}//add , remove 就不用写了,因为他是叶子节点@Overridepublic String getName() {// TODO Auto-generated method stubreturn super.getName();}@Overridepublic String getDes() {// TODO Auto-generated method stubreturn super.getDes();}@Overrideprotected void print() {// TODO Auto-generated method stubSystem.out.println(getName());}}
public static void main(String[] args) { //从大到小创建对象 学校OrganizationComponent university = new University("清华大学", " 中国顶级大学 ");//创建 学院OrganizationComponent computerCollege = new College("计算机学院", " 计算机学院 ");OrganizationComponent infoEngineercollege = new College("信息工程学院", " 信息工程学院 ");//创建各个学院下面的系(专业)computerCollege.add(new Department("软件工程", " 软件工程不错 "));computerCollege.add(new Department("网络工程", " 网络工程不错 "));computerCollege.add(new Department("计算机科学与技术", " 计算机科学与技术是老牌的专业 "));//infoEngineercollege.add(new Department("通信工程", " 通信工程不好学 "));infoEngineercollege.add(new Department("信息工程", " 信息工程好学 "));//将学院加入到 学校university.add(computerCollege);university.add(infoEngineercollege);university.print();//递归infoEngineercollege.print();}
组合模式在 JDK 集合的源码分析
Java 的集合类HashMap 就使用了组合模式


组合模式的注意事项和细节
- 简化客户端操作。客户端只需要面对一致的对象而不用考虑整体部分或者节点叶子的问题。
- 具有较强的扩展性。当我们要更改组合对象时,我们只需要调整内部的层次关系,客户端不用做出任何改动.
- 方便创建出复杂的层次结构。客户端不用理会组合里面的组成细节,容易添加节点或者叶子从而创建出复杂的树形结构
- 需要遍历组织机构,或者处理的对象具有树形结构时, 非常适合使用组合模式.
- 要求较高的抽象性,如果节点和叶子有很多差异性的话,比如很多方法和属性都不一样,不适合使用组合模式
相关文章:
【设计模式】十、组合模式
文章目录 案例组合模式基本介绍类图代码 组合模式在 JDK 集合的源码分析组合模式的注意事项和细节 案例 编写程序展示一个学校院系结构:需求是这样,要在一个页面中展示出学校的院系组成,一个学校有多个学院,一个学院有多个系。如…...
React知识点系列(8)-每天10个小知识
目录 1. 在 React 中,什么是受控组件和非受控组件?请解释一下它们之间的区别和适用场景。2. 如何使用 React 的 useReducer Hook 来管理组件状态?请描述一下 useReducer 的工作原理和适用场景。工作原理:适用场景: 3. …...
rust注释
一、普通注释 // 这是第一种注释方式/* 这是第二种注释方式 */ /* 多行注释 多行注释 多行注释*/二、文档注释 ///外部行文档注释。为接下来的项生成帮助文档 //! 内部行文档注释。为注释所属于的项生成帮助文档/**...*/外部块文档注释。为接下来的项生成帮助文档 /*!...*/内…...
【Java学习之道】GUI开发的基本概念
引言 在这一章,我们将一起走进Java的图形用户界面(GUI)开发的世界。在你阅读完这篇文章后,你将能够了解什么是GUI,以及如何使用Java进行GUI的开发。 一、什么是GUI 首先,让我们来解答一个许多初学者都会…...
Docker部署gitlab_ce(避坑版---社区版)
1 下载docker 2 下载gitlab镜像 3 运行 4 进入容器内部修改 5 在浏览器里访问 6 修改root密码(如果忘记请修改) 1 下载docker # 安装依赖 yum install -y yum-utils device-mapper-persistent-data lvm2# 设置yum源 yum-config-manager --add-repo https…...
数据仓库DW-理论知识储备
数据仓库DW 数据仓库具备 采集数据、分析数据、存储数据的功能,最后得出一些有用的数据,一些目标数据来使用。 采集来自不同源的数据,然后对这些数据进行分析和计算得出一些有用的指标,提供数据决策支持。 数据的来源有ÿ…...
SpringBoot 如何优雅的停机
这里写目录标题 1 介绍2 使用2.1 开启 hook2.2 禁用 hook 3 手动指定 hook 1 介绍 SpringBoot 如果需要使用hook则需要开启spring.main.register-shutdown-hooktrue(默认为true) 如果使用kill -9则不会出发JVM的hook,kill可以正常触发hook server:port: 8080shutd…...
详细教程:Postman 怎么调试 WebSocket
WebSocket 是一个支持双向通信的网络协议,它在实时性和效率方面具有很大的优势。Postman 是一个流行的 API 开发工具,它提供了许多功能来测试和调试 RESTful API 接口,最新的版本也支持 WebSocket 接口的调试。想要学习更多关于 Postman 的知…...
互联网Java工程师面试题·Java 并发编程篇·第五弹
目录 52、什么是线程池? 为什么要使用它? 53、怎么检测一个线程是否拥有锁? 54、你如何在 Java 中获取线程堆栈? 55、JVM 中哪个参数是用来控制线程的栈堆栈小的? 56、Thread 类中的 yield 方法有什么作用? 57、…...
mysql与oracle分页的有什么区别
Java面试:mysql与oracle分页的有什么区别 相信许多人在日常工作中都会用到分页,比如日常查询数据量太大,而我们只需要其中的几条即可,所以这时就会去使用分页去查询,今天主要就mysql与oracle的分页进行分析。 MySQL 分…...
华为云云耀云服务器L实例评测|华为云耀云服务器L实例docker部署及应用(七)
八、华为云耀云服务器L实例docker、docker-compose安装及部署MySQL、Redis应用: 随着云原生、容器化、微服务、K8S等技术的发展,容器 docker 也逐渐在企业团队实践中大量的使用。它可以提供了一套标准化的解决方案,极大地提升了部署、发布、运…...
实体解析实施的复杂性
实体的艺术表现斯特凡伯克纳 一、说明 实体解析是确定数据集中的两条或多条记录是否引用同一现实世界实体(通常是个人或公司)的过程。乍一看,实体分辨率可能看起来像一个相对简单的任务:例如,给定一张人物的两张照片&a…...
MAKEFLAGS += -rR --include-dir=$(CURDIR)的含义
一、目的 在看uboot顶层Makefile文件时遇到这个代码不甚明白,故查找了一下资料以供大家学习 二、介绍 MAKEFLAGS -rR 表示禁止使用内置的隐含规则和变量定义;这个选项用于启用recursive make,使得Makefile目标可以调用其他Makefile目标&…...
maven问题与解决方案、部署
问题一、was cached in the local repository, resolution will not be reattempted until the update interval of idea中 Maven中Lifecycle时,能正常clean 和 install,但在idea的Terminal中mvn install出现: was cached in the local repo…...
【大数据】Hadoop MapReduce与Hadoop YARN(学习笔记)
一、Hadoop MapReduce介绍 1、设计构思 1)如何对付大数据处理场景 对相互间不具有计算依赖关系的大数据计算任务,实现并行最自然的办法就是采取MapReduce分而治之的策略。 不可拆分的计算任务或相互间有依赖关系的数据无法进行并行计算! …...
接口测试文档
接口测试的总结文档 第一部分:主要从问题出发,引入接口测试的相关内容并与前端测试进行简单对比,总结两者之前的区别与联系。但该部分只交代了怎么做和如何做?并没有解释为什么要做? 第二部分:主要介绍为什…...
Ubuntu中不能使用ifconfig命令
问题 打开终端使用如下命令不能运行: ifconfig显示如下错误: 解决方法 在VMware中的虚拟机下面打开“编辑虚拟机设置”,或者在已经打开的虚拟机面板上面打开“虚拟机—设置” 选择网络适配器,选择“NAT模式”,没开机的就…...
BAT020:将文本文档中多行文本拼接为;分隔的单行文本
引言:编写批处理程序,实现将文本文档中多行文本拼接为;分隔的单行文本。 一、新建Windows批处理文件 参考博客: CSDNhttps://mp.csdn.net/mp_blog/creation/editor/132137544 二、写入批处理代码 1.右键新建的批处理文件,点击【…...
安防初识命令【学习笔记】
1、美杜莎爆破 medusa -M ssh -h 192.168.42.135 -u guest -P top1000.txt -t 8 2、passwd文件与shadow文件 root:x:0:0:root:/root:/usr/bin/zsh 用户名:密码:uid:gid:描述性信息:主目录:默认…...
idea 启动出现 Failed to create JVM JVM Path
错误 idea 启动出现如下图情况 Error launching IDEA If you already a 64-bit JDK installed, define a JAVA_HOME variable in Computer > System Properties> System Settings > Environment Vanables. Failed to create JVM. JVM Path: D:\Program Files\JetB…...
服务器很卡,是CC攻击造成的吗
之前有客户反馈,服务器有一段时间使用总是会遇到卡的情况,查看并无流量攻击的情况,程序也未进行过什么修改,用户人数也没有什么变化。来咨询是什么原因导致的。导致机器卡的情况,一般有带宽不够,硬件性能不…...
别再手动画封装了!用嘉立创EDA免费库5分钟搞定Altium Designer缺失的器件
5分钟极速救援:用嘉立创EDA破解Altium Designer封装缺失难题 深夜11点,李工盯着屏幕上闪烁的光标和半成品的PCB布局图,额头渗出细密的汗珠。项目交付截止前48小时,团队突然发现Altium Designer官方库中缺少关键芯片TPS5430DDAR的封…...
造相-Z-Image-Turbo 在嵌入式设备上的探索:基于NVIDIA Jetson的轻量化部署
造相-Z-Image-Turbo 在嵌入式设备上的探索:基于NVIDIA Jetson的轻量化部署 最近在折腾一个挺有意思的项目,想把一个叫“造相-Z-Image-Turbo”的图片生成模型,塞进像NVIDIA Jetson这样的嵌入式小盒子里。你可能知道,这类模型通常都…...
特朗普政府发布《国家人工智能立法框架》,多维度布局AI领域
【《国家人工智能立法框架》六大核心目标锚定AI发展方向】特朗普政府发布的《国家人工智能立法框架》,意在通过统一国家政策确保美国在AI领域的全球领先地位。该框架包含六大核心目标,分别是保护儿童与赋能家长、维护与强化美国社区、尊重知识产权与支持…...
威纶通宏指令实战:从零构建中文输入与智能配方检索系统
1. 威纶通触摸屏的中文输入困境与破解之道 第一次接触威纶通中低端触摸屏时,我就被它缺乏中文输入支持的问题给难住了。当时接了个食品包装机的项目,客户要求操作界面必须支持中文输入,方便工人记录生产批号和产品信息。市面上常见的中高端HM…...
我已战胜一切!感谢哥白尼,感谢爱因斯坦,感谢豆包,,,曾经我都经历过什么,我自己非常清楚,既有爱因斯坦的压缩版,又有哥白尼的压缩版,,,
不是时代不好,是人心中的成见就像一座大山般,无法被逾越,只有暴雨降下,洗刷这个世界,重塑这个宇宙,各位其位,大道至简。历史的车轮早已不可阻挡,,,暴风雨会来…...
RB3201-RBProtocol:ESP32机器人轻量通信协议栈解析
1. RB3201-RBProtocol 库深度解析:面向机器人控制的轻量级嵌入式通信协议栈 1.1 协议背景与工程定位 RB3201-RBProtocol 是由 RoboticsBrno 团队开发的嵌入式通信协议库,专为 ESP32 平台设计,核心目标是实现与 Android 端 RbController 移动…...
为什么92%的团队在MCP项目中期被迫重构?Python 4大模板的抽象泄漏、协议耦合与测试盲区深度拆解
第一章:MCP服务器开发模板的行业现状与重构困局当前,MCP(Model Control Protocol)服务器作为AI智能体协同调度与协议网关的核心组件,在金融风控、工业边缘控制、多模态Agent编排等场景中加速落地。然而,主流…...
NOR FLASH和NAND FLASH的对比
一、擦写寿命与数据可靠性 FLASH芯片的擦写次数一般来说都是有限的,目前主流产品的擦写寿命普遍在10万次左右。当FLASH芯片接近使用寿命终点时,写操作可能会出现失败。不过,需要注意NAND FLASH采用整块擦写机制,一旦块内出现一位数…...
DMA传输效率翻倍秘籍:深入解析Burst/Transfer模式在TMS320系列DSP中的配置陷阱
DMA传输效率翻倍秘籍:深入解析Burst/Transfer模式在TMS320系列DSP中的配置陷阱 实时信号处理系统的性能瓶颈往往出现在数据传输环节。当工程师面对高速ADC采集的海量数据时,DMA控制器的高效配置直接决定了系统能否实现理论上的吞吐量。本文将深入剖析TMS…...
