【设计模式】十、组合模式

文章目录

  • 案例
  • 组合模式
    • 基本介绍
    • 类图
    • 代码
  • 组合模式在 JDK 集合的源码分析
  • 组合模式的注意事项和细节

案例

编写程序展示一个学校院系结构:需求是这样,要在一个页面中展示出学校的院系组成,一个学校有多个学院,一个学院有多个系。如图:
在这里插入图片描述传统方案解决学校院系展示(类图)
在这里插入图片描述
传统方案解决学校院系展示存在的问题分析:

  1. 将学院看做是学校的子类,系是学院的子类,这样实际上是站在组织大小来进行分层次的
  2. 实际上我们的要求是 :在一个页面中展示出学校的院系组成,一个学校有多个学院,一个学院有多个系, 因此这种方案,不能很好实现的管理的操作,比如对学院、系的添加,删除,遍历等
  3. 解决方案:把学校、院、系都看做是组织结构,他们之间没有继承的关系,而是一个树形结构,可以更好的实现管理操作。 => 组合模式

组合模式

基本介绍

  1. 组合模式(Composite Pattern),又叫部分整体模式,它创建了对象组的树形结构,将对象组合成树状结构以表示“整体-部分”的层次关系。
  2. 组合模式依据树形结构来组合对象,用来表示部分以及整体层次。
  3. 这种类型的设计模式属于结构型模式。
  4. 组合模式使得用户对单个对象和组合对象的访问具有一致性,即:组合能让客户以一致的方式处理个别对象以及组合对象

类图

在这里插入图片描述对原理结构图的说明-即(组合模式的角色及职责):

  1. Component :这是组合中对象声明接口,在适当情况下,实现所有类共有的接口默认行为,用于访问和管理Component 子部件, Component 可以是抽象类或者接口
  2. Leaf : 在组合中表示叶子节点,叶子节点没有子节点
  3. 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 就使用了组合模式
在这里插入图片描述
在这里插入图片描述

组合模式的注意事项和细节

  1. 简化客户端操作。客户端只需要面对一致的对象而不用考虑整体部分或者节点叶子的问题。
  2. 具有较强的扩展性。当我们要更改组合对象时,我们只需要调整内部的层次关系,客户端不用做出任何改动.
  3. 方便创建出复杂的层次结构。客户端不用理会组合里面的组成细节,容易添加节点或者叶子从而创建出复杂的树形结构
  4. 需要遍历组织机构,或者处理的对象具有树形结构时, 非常适合使用组合模式.
  5. 要求较高的抽象性,如果节点和叶子有很多差异性的话,比如很多方法和属性都不一样,不适合使用组合模式

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

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

相关文章

Kotlin笔记(四):高阶函数

1. 高阶函数 1.1 定义高阶函数 高阶函数和Lambda的关系是密不可分的。一些与集合相关的函数式API的用法&#xff0c;如map、filter函数等,Kotlin的标准函数&#xff0c;如run、apply函数等。这几个函数有一个共同的特点&#xff1a;它们都会要求我们传入一个Lambda表达式作为参…

4.查询用户的累计消费金额及VIP等级

思路分析&#xff1a; &#xff08;1&#xff09;按照user_id及create_date 分组求消费金额total_amount &#xff08;2&#xff09;开窗计算同user_id下的累计销售金额sum(total_amount) over(partition by user_id order by create_date ROWS BETWEEN UNBOUNDED PRECEDING AN…

07测试Maven中依赖的范围,依赖的传递原则,依赖排除的配置

依赖的特性 scope标签在dependencies/dependency标签内,可选值有compile(默认值),test,provided,system,runtime,import compile&#xff1a;在项目实际运行时真正要用到的jar包都是以compile的范围进行依赖 ,比如第三方框架SSM所需的jar包test&#xff1a;测试过程中使用的j…

windows OpenCV(包含cuda)最简安装教程

windows OpenCV&#xff08;包含cuda&#xff09;最简安装教程 1. 在Windows下安装vcpkg vcpkg是一个开源的C包管理器&#xff0c;它能帮助我们轻松地安装和管理C库和工具。要在Windows上安装vcpkg&#xff0c;可以按照以下步骤进行&#xff1a; 克隆vcpkg仓库&#xff1a; 首…

CustomShapes/自定义形状, CustomCurves/自定义曲线, AnimateableData/数据变化动画 的使用

1. CustomShapes 自定义形状视图 1.1 资源图文件 therock.png 1.2 创建自定义形状视图 CustomShapesBootcamp.swift import SwiftUI/// 三角形 struct Triangle: Shape{func path(in rect: CGRect) -> Path {Path { path inpath.move(to: CGPoint(x: rect.midX, y: rect.mi…

云原生网关可观测性综合实践

作者&#xff1a;钰诚 可观测性 可观测性&#xff08;Observability&#xff09;是指系统、应用程序或服务的运行状态、性能和行为能够被有效地监测、理解和调试的能力。 随着系统架构从单体架构到集群架构再到微服务架构的演进&#xff0c;业务越来越庞大&#xff0c;也越来…

数字孪生在制造运行管理(MOM)的七大应用场景

数字经济时代&#xff0c;数字孪生作为实现各行各业智能化、数字化的重要手段之一&#xff0c;受到了各方的广泛重视。随着各项关键使能技术的不断发展&#xff0c;数字孪生的应用价值有望得到进一步释放。这些关键使能技术包括建模、渲染、仿真、物联网、虚拟调试、可视化等&a…

02_单片机及开发板介绍

单片机简介 单片机&#xff0c;又称为微控制器&#xff08;Microcontroller&#xff09;&#xff0c;是一种集成了微处理器核心、存储器、输入/输出接口及各种功能模块的集成电路芯片。它通常由中央处理器&#xff08;CPU&#xff09;、存储器、输入/输出接口以及各种外设组成&…

文献阅读快速法-ChatPDF

如题&#xff0c;直接提供给大家一款能够快速阅读文档的好工具——iTextMaster。 iTextMaster是一款免费的pdf阅读浏览器&#xff0c;上传pdf文档后等待几秒钟&#xff0c;AI就会自动反馈给用户关于文档的摘要总结。十分的方便且实用。 ChatPDF为您提供简洁的文档摘要。对于那…

【算法|动态规划No.21】leetcode494. 目标和

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【手撕算法系列专栏】【LeetCode】 &#x1f354;本专栏旨在提高自己算法能力的同时&#xff0c;记录一下自己的学习过程&#xff0c;希望…

8月19日PMP成绩,预计10月16日公布!附查询入口、流程

PMP的考试成绩一般在考后6-8周即可查询&#xff0c;8月PMP的成绩预计会在北京时间10月16日晚上公布&#xff0c;具体时间以官方公告为准。 如何查询8月考试成绩&#xff1f; 渠道一&#xff1a;收到PMI邮件提醒 当你注册PMI所使用的邮箱收到一封PMI发来的&#xff0c;标题为…

全波形反演的目标和技术

本篇文章主要讲述了全波形反演的目标和可能用到的方法&#xff0c;对其概念进行解释&#xff0c;以加深理解。若有不正确的地方&#xff0c;欢迎批评指正。 一. 全波形反演的目标: 1. 如何保障模型的拟合能力? 2. 如何保障模型的泛化能力? 3. 如何使结果 (速度模型) 满足物理…

Scrapy框架中的Middleware扩展与Scrapy-Redis分布式爬虫

在爬虫开发中&#xff0c;Scrapy框架是一个非常强大且灵活的选择。在本文中&#xff0c;我将与大家分享两个关键的主题&#xff1a;Scrapy框架中的Middleware扩展和Scrapy-Redis分布式爬虫。这些主题将帮助你更好地理解和应用Scrapy框架&#xff0c;并提升你的爬虫开发技能。 …

【位运算】必知必会:二进制位的原码反码补码转换 以及 按位与、按位或|、异或^

二进制位的原码反码补码转换 以及 按位与&、按位或|、异或^ 一、二进制位的原码、反码、补码转换1.机器数2.原码3.反码4.补码 二、按位与&、按位或|、异或^ 最近在练习LeetCode上的算法题&#xff0c;遇到了位运算求解的问题&#xff0c;作以复习总结。 一、二进制位的…

『PyQt5-Qt Designer篇』| 13 Qt Designer中如何给工具添加菜单和工具栏?

13 Qt Designer中如何给工具添加菜单和工具栏? 1 创建默认窗口2 添加菜单栏3 查看和调用1 创建默认窗口 当新创建一个窗口的时候,默认会显示有:菜单栏和状态栏,如下: 可以在菜单栏上右键-移除菜单栏: 可以在菜单栏上右键-移除状态栏: 2 添加菜单栏 在窗口上,右键-创建…

软件测试定位bug方法+定位案例(详解)

1、问题bug定位技巧 首先&#xff0c;作为开发也好&#xff0c;测试也好&#xff0c;定位问题有一个总的思路&#xff0c;而这个思路是和数据的走向一致的。 大致是这样&#xff1a; 用户层面问题 -> Web页面/软件界面 -> 中间件 -> 后端服务 -> 代码 -> 数据…

【Kubeedge小白安装教程】Centos7.9+K8Sv1.22.17(kubeadm)+Kubeedgev1.13.1部署教程详解----亲测过

第一&#xff1a;部署kubernetes1.22版本 这里部署k8s版本为1.22或者1.23版本。这里参考kubeedge支持的程度&#xff0c;选择1.22版本&#xff0c;后续会支持更高的k8s版本。 相关部署环境及部署组件&#xff1a; 主机名ip地址节点类型系统版本k8s-master192.168.0.61master…

简易的慢SQL自定义告警实战经验(支持多数据源)

背景 对于慢SQL相信大家都不陌生了,一旦遇到后,相信大家会很快的提供出来对应的优化方法、索引优化建议工具使用等等,对于此我相信大家已经熟悉的不能再熟悉了,但是比较不尽人意的是:在此之前我们往往是花费了大量时间才发现造成系统出现问题的是慢SQL引起的,风险自然而…

如何正确维护实验室超声波清洗器?

实验室一直被视为一个严谨而严肃的场所&#xff0c;实验应遵循一定的步骤&#xff0c;使用的设备也经历了详细的选择&#xff0c;如实验室超声波清洗机&#xff0c;其特点远强于一般类型的清洗机。专门负责采购的实验室人员一般对优质服务的实验室超声波清洗机印象深刻&#xf…

故障维修无忧服务:OLED透明拼接屏的专业技术支持与保修服务

OLED透明拼接屏作为未来显示技术的领军者&#xff0c;以其卓越的画质和全方位的优势在市场上备受推崇。 本文将深入探讨OLED透明拼接屏的画质特点和独有的优势&#xff0c;并为您提供选购指南、价格表以及故障维修服务&#xff0c;助您了解并选择最适合的OLED透明拼接屏。 一、…