当前位置:网站首页>组合模式
组合模式
2022-08-10 17:36:00 【老蛙@】
学校院系展示需求
需要在一个页面中,展示出学校的院系组成,一个学校有多个学院,一个学院有多个系
传统方案解决学校院系展示
- 将学院看作是学校的子类,系是学院的子类,这样实际上是站在组织大小进行分层次的
- 但实际上的要求是:在一个页面中展示出学校的院系组成,这样的方案不便于管理,如对学院、系的增加、删除、遍历等
组合模式
基本介绍
- 组合模式,又叫部分整体模式,他创建了对象组的树形结构,将对象那个组合成树状结构以表示整体-部分的层次关系
- 组合模式依据树形结构来组合对象,用来表示部分以及整体层次
- 组合模式数据结构型模式
- 组合模式使得用户对单个对象和组合对象的访问具有一致性,即组合能让客户以一直的方式处理个别对象以及组合对象
原理
- Component:组合中对象声明抽象,实现所有类共有的接口默认行为,用于访问和管理Component子部件,可以是抽象类和接口
- SubMenu:表示叶子结点,最下层的被管理者
- Composite:非叶子结点,用于存储子部件,实现Component中对子部件的相关操作;充当管理者,被父级管理,管理子级
应用场景
当需要处理的对象能够生成树形结构,而需要对树的结点和叶子进行操作时,它能够提供一直的方式,不论是结点还是叶子
组合模式解决院系展示
/*** * @author shaofan * @Description 组合模式解决院系展示问题 */
public class Composite {
public static void main(String[] args) {
Department department = new Department("软件工程","软件");
Department department2 = new Department("计算机科学与技术","计算");
College college1 = new College("计算机学院","计算机学院");
College college2 = new College("艺术学院","艺术学院");
University university = new University("xx大学","大学");
college1.add(department);
college1.add(department2);
university.add(college1);
university.add(college2);
university.print();
}
}
abstract class OrganizationComponent{
private String name;
private String desc;
public OrganizationComponent(String name,String desc){
this.name = name;
this.desc = desc;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
// 增加方法和修改方法默认实现,抛出不支持操作的异常
protected void add(OrganizationComponent organizationComponent){
throw new UnsupportedOperationException();
}
protected void remove(OrganizationComponent organizationComponent){
throw new UnsupportedOperationException();
}
/** * 抽象的打印方法,具体有子类实现 */
protected abstract void print();
}
class University extends OrganizationComponent{
List<OrganizationComponent> colleges = new ArrayList<>();
public University(String name, String desc) {
super(name, desc);
}
@Override
protected void add(OrganizationComponent organizationComponent) {
colleges.add(organizationComponent);
}
@Override
protected void remove(OrganizationComponent organizationComponent) {
colleges.remove(organizationComponent);
}
@Override
protected void print() {
System.out.println("----------"+getName()+"------------"+getDesc()+"---------------");
for (OrganizationComponent college : colleges) {
college.print();
}
}
}
class College extends OrganizationComponent{
List<OrganizationComponent> departments = new ArrayList<>();
public College(String name, String desc) {
super(name, desc);
}
@Override
protected void add(OrganizationComponent organizationComponent) {
departments.add(organizationComponent);
}
@Override
protected void remove(OrganizationComponent organizationComponent) {
departments.remove(organizationComponent);
}
@Override
protected void print() {
System.out.println("------"+getName()+"------"+getDesc()+"-------");
for (OrganizationComponent department : departments) {
department.print();
}
}
}
class Department extends OrganizationComponent{
public Department(String name, String desc) {
super(name, desc);
}
// 叶子结点不实现管理方法
@Override
protected void print() {
System.out.println(getName()+"--"+getDesc());
}
}
源码分析
在Java中的HashMap使用了组合模式
- Map和AbstractMap就是一个抽象的构建,类似Component
- HashMap就是中间的构建,即Composite,他管理了底层的叶子结点,实现了put、putall具体的管理方法
- Node是HashMap的静态内部类,类似叶子结点,内部没有了put、putAll等管理方法
总结
- 简化了caller的操作,caller只需要面对一致的对象而不用考虑整体部分或者结点叶子的问题
- 具有较强的扩展性,当需要更改组合对象时,只需要调整内部的层次关系,caller不用做出任何改动,符合开闭原则
- 方便创建出复杂的层次结构,caller不用例会组合里面的组成细节,容易添加结点或者叶子,从而创建出复杂的树形结构
- 需要遍历不同层次,或者处理的对象具有树形结构时,非常适合使用组合模式
- 要求较高的抽象性,如果结点和叶子有很多的差异性的话,比如很多方法和属性都不一样,不适合使用组合模式
边栏推荐
猜你喜欢
【云原生| Docker】 部署 Django & mysql 项目
DGIOT平台实时展示OPC上报数据全流程代码剖析
机器人控制器编程实践指导书旧版-实践三 直流电机(执行器)
【严重】Nps 鉴权绕过 0day 漏洞
D-Wave成功上市!量子计算商业化正在加速
Before opening a futures account, you must confirm the handling fee as soon as possible
Product Description丨MobPush fast integration method on Android side
Toronto Research Chemicals萜烯分析丨反式植物醇
中国芯片的营收首破万亿,优势凸显的成熟工艺产能将称霸全球
老板加薪!看我做的WPF Loading!!!
随机推荐
oracle11g体系结构
浅谈泰山众筹系统开发技术说明及dapp链上众筹系统开发分析
Toronto Research Chemicals农药检测丨Naled-d6
FFmpeg 从mp4上提取H264的nalu
pip安装时 fatal error C1083 无法打开包括文件 “io.h” No such file or directory
老板加薪!看我做的WPF Loading!!!
WebRTC源码分析 nack详解
全新接口——邻家好货 API
pip install fatal error C1083 cannot open include file "io.h" No such file or directory
shopee API 接入说明
BalsnCTF2021
中国芯片的营收首破万亿,优势凸显的成熟工艺产能将称霸全球
Word里表格跨页时自动断开,表格后留有空白部分,未布满整页,如何操作让表格上下页均匀布满?
文档标题能否支持公式
还在用 Xshell?你 out 了,推荐一个更现代的终端连接工具,好用到爆!
PS2手柄通讯协议解析—附资料和源码「建议收藏」
DASCTF2022.07赋能赛 WEB题目复现
【Web3 系列开发教程——创建你的第一个 NFT(8)】如何开发一个成功的 NFT 项目 | NFT 社区建设技巧
ZLMediaKit 服务器源码解读---RTSP推流拉流
《安富莱嵌入式周报》第277期:业界首款Cortex-M55+Ethos-U55 NPU套件发布,20个墨水屏菊花链玩法,氙气灯镇流器设计