当前位置:网站首页>组合模式

组合模式

2022-08-10 17:36:00 老蛙@

学校院系展示需求

需要在一个页面中,展示出学校的院系组成,一个学校有多个学院,一个学院有多个系

传统方案解决学校院系展示

在这里插入图片描述

  1. 将学院看作是学校的子类,系是学院的子类,这样实际上是站在组织大小进行分层次的
  2. 但实际上的要求是:在一个页面中展示出学校的院系组成,这样的方案不便于管理,如对学院、系的增加、删除、遍历等

组合模式

基本介绍

  1. 组合模式,又叫部分整体模式,他创建了对象组的树形结构,将对象那个组合成树状结构以表示整体-部分的层次关系
  2. 组合模式依据树形结构来组合对象,用来表示部分以及整体层次
  3. 组合模式数据结构型模式
  4. 组合模式使得用户对单个对象和组合对象的访问具有一致性,即组合能让客户以一直的方式处理个别对象以及组合对象

原理

在这里插入图片描述

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

  1. Map和AbstractMap就是一个抽象的构建,类似Component
  2. HashMap就是中间的构建,即Composite,他管理了底层的叶子结点,实现了put、putall具体的管理方法
  3. Node是HashMap的静态内部类,类似叶子结点,内部没有了put、putAll等管理方法

总结

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

版权声明
本文为[老蛙@]所创,转载请带上原文链接,感谢
https://blog.csdn.net/m0_48468380/article/details/126267689