java23种设计模式——八、组合模式

目录

java23种设计模式—— 一、设计模式介绍
java23种设计模式—— 二、单例模式
java23种设计模式——三、工厂模式
java23种设计模式——四、原型模式
java23种设计模式——五、建造者模式
java23种设计模式——六、适配器模式
java23种设计模式——七、桥接模式
java23种设计模式——八、组合模式

介绍

组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。

这种模式创建了一个包含自己对象组的类。该类提供了修改相同对象组的方式。

组合模式类似树形结构,上一层节点的包含多个下一层的节点,而下一层的节点只依附于一个上一层的节点。

实现

我们先来看下组合模式的角色。

  • Component抽象构建角色,抽象共有的方法和属性,
  • Leaf叶子构件,叶子对象,没有其他分支,类似于树叶
  • Composite数值构件,组合叶子和其他树枝组合成一个完整的树,类似于树枝

通常大学里都有很多个系,每个系又包含多个专业,每个专业也有多个班级。

首先有一个抽象学校类,即component角色

/**
 * @author codermy
 * @createTime 2020/7/28
 */
//学校
public abstract class School {
    //展示树形结构
    public abstract void display(String f);
    //添加分支
    public void add(School branch){
        throw new UnsupportedOperationException("不支持此功能");
    };
    //删除分支
    public void remove(School branch) {
        // 若叶子对象没有这个功能,或子类未实现这个功能
        throw new UnsupportedOperationException("不支持此功能");
    }

}

现在有一个Branch类(即Composite角色)继承了学校类,并实现其中方法。我们可以把它抽象的想成,学校的分院与专业的结构都一样,所以新建它们都公用这一个类

/**
 * @author codermy
 * @createTime 2020/7/28
 * 分院
 */
public class Branch extends School {
    //学校集合
    private List<School> schoolList = new ArrayList<>();

    private String name;

    public Branch(String name){
        this.name=name;
    }

    @Override
    public void display(String f) {
        System.out.println(f + name);
        // 如果还包含其他子组件,那么就输出这些子组件对象
        if (null != schoolList) {
            // 添加一个空格,表示向后缩进一个空格
            f += "---";
            // 输出当前对象的子组件对象
            for (School school : schoolList) {
                // 递归地进行子组件相应方法的调用,输出每个子组件对象
                school.display(f);
            }
        }
    }

    public void add(School branch){
        schoolList.add(branch);
    }

    public void remove(School branch){
        schoolList.remove(branch);
    }
}

而学校里最小的单元是班级,新建这个类(即Leaf)

/**
 * @author codermy
 * @createTime 2020/7/28
 */
public class Class extends School {
    private String name;

    public Class(String name){
        this.name = name;
    }

    @Override
    public void display(String f) {
        System.out.println(f + "-"+ name);
    }
}

client类测试

/**
 * @author codermy
 * @createTime 2020/7/28
 */
public class Client {
    public static void main(String[] args) {
        //新建一个学校
        School university = new Branch("南京大学");
        //新建分院
        School branch1 = new Branch("计算机与软件学院");
        School branch2 = new Branch("外国语学院");
        //新建专业
        School profession1 = new Branch("软件工程");
        School profession2 = new Branch("网络工程");
        //新建班级
        profession1.add(new Class("软件1801"));
        profession1.add(new Class("软件1802"));

        branch1.add(profession1);
        branch1.add(profession2);
        university.add(branch1);
        university.add(branch2);
        university.display("-");
    }
}

输出

-南京大学
----计算机与软件学院
-------软件工程
-----------软件1801
-----------软件1802
-------网络工程
----外国语学院

优缺点

优点:

  • 1、高层模块调用简单。
  • 2、节点自由增加。
  • 3、可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,使得增加新构件也更容易。

缺点:

  • 1、在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则。
  • 2、使设计变得更加抽象,对象的业务规则如果很复杂,则实现组合模式具有很大挑战性。
posted @ 2020-08-29 09:15  codermy  阅读(568)  评论(0编辑  收藏  举报