【结构型模式】组合模式

一、组合模式概述

        组合模式的定义与意图将对象组合成树形结构来表现“整体/部分”层次结构。组合能让客户以一致的方式处理个别对象以及对象组合。(对象结构型)

  • 组合模式分析
    • 1.当容器对象的某一个方法被调用时,将遍历整个树形结构,寻找也包含这个方法的成员对象并调用执行,牵一而动百,其中使用了递归调用的机制来对整个结构进行处理;
    • 2.由于容器对象和叶子对象在功能上的区别,在使用这些对象的代码中必须有区别地对待容器对象和叶子对象,而实际上大多数情况下客户端希望一致地处理它们,因为对于这些对象的区别对待将会使程序非常复杂。
  • 如何一致地对待容器对象和叶子对象?
    • 组合模式通过一种巧妙地设计方案使得用户可以一致性地处理整个树形结构或者树形结构地一部分,它描述了如何将容器对象和叶子对象进行递归组合,使得用户在使用时无须对它进行区分,可以一致地对待容器对象和叶子对象。
  • 安全组合模式
    • 1.抽象构件Component中没有声明任何用于管理成员对象的方法,而是在Composite类中声明并实现这些方法;
    • 2.对于叶子对象,客户端不可能调用到这些方法;
    • 3.缺点是不够透明,客户端不能完全针对抽象编程。必须有区别地对待叶子构件和容器构件。
  • 透明组合模式
    • 1.抽象构件Component中声明了所有用于管理成员对象的方法,包括add()、remove()、以及getChild()等方法;
    • 2.在客户端看来,叶子对象与容器对象所提供的方法是一致的,客户端可以一致地对待所有的对象;
    • 3.缺点是不够安全,因为叶子对象和容器对象在本质上是有区别的。
  • 组合模式的优缺点
    • 优点
      • 1.可以清楚的定义分层次的复杂对象,表示对象的全部或部分层次,让客户端忽略了层次的差异,方便对整个层次结构将进行控制;
      • 2.客户端可以一致地使用一个组合结构或其中单个对象,不必关心处理的是单个对象还是整个组合结构,简化了客户端代码;
      • 3.增加新的容器构件和叶子构件都很方便,符合开闭原则;
      • 4.为树形结构的面向对象实现提供了一种灵活的解决方案。
    • 缺点
      • 在增加新构件时很难对容器中的构件类型进行限制。
  • 适用环境
    • 1.在具有整体和部分的层次结构中,希望通过一种方式忽略整体与部分的差异,客户端可以一致地对待他们;
    • 2.在一个使用面向对象语言开发的系统中需要处理一个树形结构;
    • 3.在一个系统中能够分离出叶子对象和容器对象,而且它们的类型不固定,需要增加一些新的类型。

二、代码实现

        组合模式的结构:

  • Component(抽象构件)
  • Leaf(叶子构件)
  • Composite(容器构件)

        某教育机构组织结构如下图所示:

        在该教育机构的OA系统中可以给各级办公室下发公文,试采用组合模式设计该机构的组织结构,绘制相应的类图并编程模拟实现,在客户端代码中模拟下发公文。

        2.1 Component(抽象构件类:AbstractHead)
package composite.OAteacher;
//(1)Component抽象构件类:AbstractHead
public abstract class AbstractHead {
	public abstract void receiveDocument();
}
        2.2 Leaf(叶子构件:AdminOffice、ProvostOffice)
package composite.OAteacher;
//(2.1)Leaf叶子构件类:AdminOffice
public class AdminOffice extends AbstractHead {	
	private String officeName;	
	public AdminOffice(String officeName){
		this.officeName = officeName;
	}	
	public void receiveDocument(){
		System.out.println(officeName + "收到文件");
	}
}
package composite.OAteacher;
//(2.2)Leaf叶子构件类:ProvostOffice
public class ProvostOffice extends AbstractHead {
	
	private String officeName;	
	public ProvostOffice(String officeName){
		this.officeName = officeName;
	}	
	public void receiveDocument(){
		System.out.println(this.officeName + "收到文件...");
	}	
}
        2.3 Composite(容器构件:Branch,定义构件行为)
package composite.OAteacher;

import java.util.*;
//(3)composite:定义组件行为,比如下发文件动作
public class Branch extends AbstractHead {	

	private String branchName;
	ArrayList list = new ArrayList();	

	public Branch(String branchName){
		this.branchName = branchName;
	}	
	public void addSubOrg(AbstractHead elment){
		list.add(elment);
	}	
	public void removeSubOrg(AbstractHead element){
		list.remove(element);
	}	
	public void receiveDocument(){		
		System.out.println("-----------------------------------------");
		for(Object object: list){
			//System.out.println(object.getClass());
			if(object.getClass().toString().equals("class Branch"))
			{				
				((Branch)object).issudedDocument();
			}
			else
				((AbstractHead)object).receiveDocument();			
		}		
	}
	public void issudedDocument(){
		System.out.println(branchName + "下发文件......");
		this.receiveDocument();
	}
}
        2.4 main方法实现组合模式
package composite.OAteacher;
//(5)客户端测试类:Client
/*
 * 题目:
某教育机构组织结构如下图所示:
在该教育机构的OA系统中可以给各级办公室下发公文,现采用组合模式设计该机构的组织结构,绘制相应的类图并编程模拟实现,在客户端代码中模拟下发公文。
 */
public class Client {	
	public static void main(String args[]){	
	
		AbstractHead office11 = new ProvostOffice("长沙教学点教务办公室");
		AbstractHead office12 = new ProvostOffice("长沙教学点行政办公室");
		Branch b1 = new Branch("长沙教学点");
		b1.addSubOrg(office11);
		b1.addSubOrg(office12);
		
		AbstractHead office21 = new ProvostOffice("湘潭教学点教务办公室");
		AbstractHead office22 = new ProvostOffice("湘潭教学点行政办公室");
		Branch b2 = new Branch("湘潭教学点");
		b2.addSubOrg(office21);
		b2.addSubOrg(office22);
		
		AbstractHead office31 = new ProvostOffice("湖南分校教务办公室");
		AbstractHead office32 = new ProvostOffice("湖南分校行政办公室");
		Branch b3 = new Branch("湖南分校");
		b3.addSubOrg(office31);
		b3.addSubOrg(office32);
		b3.addSubOrg(b1);
		b3.addSubOrg(b2);
		
		AbstractHead office41 = new ProvostOffice("北京总部教务办公室");
		AbstractHead office42 = new ProvostOffice("北京总部行政办公室");
		Branch b4 = new Branch("北京总部");
		b4.addSubOrg(office41);
		b4.addSubOrg(office42);
		b4.addSubOrg(b3);
		
		b4.issudedDocument();
		//b4.receiveDocument();		
	}
}
        2.5 UML图

三、代码结构图

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

OpenHarmony网络协议通信—kcp

kcp 是一种 ARQ 协议,可解决在网络拥堵情况下 tcp 协议的网络速度慢的问题 下载安装 直接在 OpenHarmony-SIG 仓中搜索 kcp 并下载。 使用说明 准备一套完整的 OpenHarmony 3.1 Beta 代码 库代码存放路径:./third_party/kcp 修改添加依赖的编译脚本 在/develo…

书生·浦语实战营第二期(六)——Agent

一、概述: 1.1、Lagent: Lagent 是一个轻量级开源智能体框架,旨在让用户可以高效地构建基于大语言模型的智能体。同时它也提供了一些典型工具以增强大语言模型的能力。 Lagent 目前已经支持了包括 AutoGPT、ReAct 等在内的多个经典智能体范式&#xf…

jeecgflow之camunda工作流-串行流程

引言 UserTask用户任务,是需要人处理后才能流转的任务。 本文将构建一个简单的串行流程带大家快速入门camunda工作流。 BPMN在线建模 如需亲自体验文章案例,请访问如下网址。 JeecgFlow演示站点 需求 我们以三国为背景, 假设系统中拥有将军&#xff0c…

ardunio中自定义的库文件

1、Arduino的扩展库都是放在 libraries目录下的。完整路径为:C:\Users\41861\AppData\Local\Arduino15\libraries 所以我们需要在这个目录下创建一个文件夹,比如上面的例子是esp32上led灯控制程序,于是我创建了 m_led文件夹(前面加…

根据 Excel 列生成 SQL

公司有个历史数据刷数据的需求, 开发功能有点浪费, 手工刷数据有点慢, 所以研究了下 excel 直接生成 SQL, 挺好用, 记录一下; 例如这是我们的数据, 要求把创建时间和完成时间刷进数据库中, 工单编号唯一 Excel 公式如下: "UPDATE service_order SET create…

浅析Redis④:字典dict实现

什么是dict? 在 Redis 中,dict 是指哈希表(hash table)的一种实现,用于存储键值对数据。dict 是 Redis 中非常常用的数据结构之一,用于实现 Redis 的键空间。 在 Redis 源码中,dict 是一个通用…

linux中如何挂载yum云仓库进行软件的安装

1.首先在根目录下建立文件,用来挂载镜像文件 [rootclient ~]# mkdir /rhel9 2.挂载镜像文件: [rootclient ~]# mount /dev/cdrom /rhel9 3.切换到 /etc/yum.repos.d 下的目录并查看 ,创建 rhel9.repo文件,并编辑云仓库域名&am…

【LLM 论文】Self-Consistency — 一种在 LLM 中提升 CoT 表现的解码策略

论文:Self-Consistency Improves Chain of Thought Reasoning in Language Models ⭐⭐⭐⭐⭐ ICLR 2023, Google Research 文章目录 论文速读 论文速读 本工作提出了一种解码策略:self-consistency,并可以用于 CoT prompting 中。 该策略提…

Linux使用Libevent库实现一个网页服务器---C语言程序

Web服务器 这一个库的实现 其他的知识都是这一个专栏里面的文章 实际使用 编译的时候需要有一个libevent库 gcc httpserv.c -o httpserv -levent实际使用的时候需要指定端口以及共享的目录 ./httpserv 80 .这一个函数会吧这一个文件夹下面的所有文件共享出去 实际的效果, 这…

NLP_知识图谱_三元组实战

文章目录 三元组含义如何构建知识图谱模型的整体结构基于transformers框架的三元组抽取baselinehow to use预训练模型下载地址训练数据下载地址 结构图代码及数据bertconfig.jsonvocab.txt datadev.jsonschemas.jsontrain.jsonvocab.json 与bert跟data同个目录model.pytrain.py…

华为ensp中rip和ospf路由重分发 原理及配置命令

作者主页:点击! ENSP专栏:点击! 创作时间:2024年4月20日20点21分 路由重分发(Route Redistribution)是指路由器将从一种路由协议学习到的路由信息,通过另一种路由协议通告出去的功…

Linux环境变量深度解析

文章目录 一、引言二、环境变量的基本概念1、环境变量的定义2、环境变量的作用与意义 三、环境变量的导入1、导入所需文件2、登陆时的导入 四、环境变量的设置方法1、查看环境变量的方式2、使用export命令临时设置环境变量3、修改配置文件以永久设置环境变量 五、命令行参数与环…

Python编程与算法面试-编程面试的重点

在求职面试的过程中,编程能力也是面试官非常看重的一项能力。而对于编程这项能力主要的考察点也有三个维度: 初级:编程的基本功 编程的基本功主要考察的编程语言的基本语法,原理知识,以及一些在编程过程中的常见问题…

基于unity+c#的随机点名系统(简单UI界面+列表+数组)

目录 一、功能界面显示 二、UI 1、视频的使用 (1)渲染纹理 (2) 视频铺全屏 (3)视频的调用 2、 下拉文本框的使用(旧版) 3、输入文本框的使用(旧版) …

OpenHarmony 视图加载——ImageViewZoom

简介 ImageViewZoom 支持加载 Resource 或 PixelMap 图片,支持设置图像显示类型功能,支持缩放功能,支持平移功能,双击放大功能,可以监听图片大小,资源变化事件,支持清除显示图片功能。 效果展示…

pg内核之日志管理器(五)WAL日志

概念 WAL日志 数据库运行过程中,数据一般是会保存在内存和磁盘中,为保证数据的安全性,防止数据库崩溃时数据不丢失,一般都是要保证数据实时落盘的,但是又由于磁盘随机IO读写速率与内存相比慢很多,如果每个…

RocketMQ5.x的pop模式如何解决消费堆积问题

RocketMQ4.X现存问题 消费能力不能随POD增加而增加。 理想情况下,POD数量小于QUEUE的数量,增加机器是能提高消能力的。 现实情况下,如果POD数量大于QUEUE的数量,那么多的POD机器就不会处理消费,是一种资源的浪费。 单…

苹果 IPA 应用部署软件 iMazing 3 Windows 版获 3.0.0.4 Beta 4

在数字化时代,我们的iOS设备已经成为生活中不可或缺的一部分。为了更加高效、便捷地管理这些设备,iMazing 3.0.0.3 应运而生,它以其独特的功能和卓越的性能,为用户带来了前所未有的全新体验。 首先,iMazing 3.0.0.3 提…

集简云数据表新增批量操作功能,一键实现批量触发执行对应自动化流程

在使用数据表时,某些情况下可能希望人工触发自动化流程执行,例如:开发票、提交工单、同步帐套信息等场景。 通过数据表按钮字段,可手动触发执行对应自动化流程,实现将数据推送到其他表单、应用系统,或从其…

C++必修:从C语言到C++的过渡(上)

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:C学习 贝蒂的主页:Betty’s blog 1. 什么是C C(c plus plus)是一种计算机高级程序设计语言&…