当前位置:网站首页>组合模式
组合模式
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不用例会组合里面的组成细节,容易添加结点或者叶子,从而创建出复杂的树形结构
- 需要遍历不同层次,或者处理的对象具有树形结构时,非常适合使用组合模式
- 要求较高的抽象性,如果结点和叶子有很多的差异性的话,比如很多方法和属性都不一样,不适合使用组合模式
边栏推荐
猜你喜欢
随机推荐
WebRTC source code analysis nack detailed explanation
mysql主主复制+keepalived高可用
架构-三层架构:三层架构
FFmpeg花屏解决(修改源码,丢弃不完整帧)
DeamNet代码学习||网络框架核心代码 逐句查找学习
成为一个优秀的测试工程师需要具备哪些知识和经验?
Colocate Join :ClickHouse的一种高性能分布式join查询模型
Toronto Research Chemicals农药检测丨Naled-d6
CDH6.3.2之Kerberos安全认证_大数据培训
mysql定义存储过程
The DGIOT platform displays the whole process code analysis of OPC reporting data in real time
HDLBits: 在线学习 SystemVerilog(零)-在线“巡礼” HDLBits
ROBOTSTXT_OBEY[通俗易懂]
机器人控制器编程实践指导书旧版-实践八 机器人综合设计
忍不住 - 发个新帖子【为什么把红圈的功能入口隐藏?需要移动到鼠标到位置驻停才显示?】- 请投票
不能直接在交易所期货开户
机器人控制器编程实践指导书旧版-实践六 LCD液晶显示(点阵)
海思HI3516DV300开发资料
「Web应用架构」轮询,SSE 和WebSocket,如何选择合适的?
【云原生| Docker】 部署 Django & mysql 项目