【设计模式】组合模式?建议改名叫树形模式!

?设计模式目录

什么是组合模式(Composite)

概念

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

组合模式关注的是对象间的结构,希望能够让调用者在使用一组对象时和使用单个对象没什么区别,屏蔽掉组合对象和单个对象的差别

个人感觉组合模式应该叫做树形模式,当对象呈现成树形结构时,使用这个模式就非常的好了,建议改名。

我不要你觉得,我要我觉得

组合模式分为两种:透明式组合模式和安全式组合模式。

透明式组合模式:所有的对象都是使用同一个接口,不会区分对象之间的差别,使用者使用起来是区分不了的。树叶构件也会实现树枝构件的方法,但是是空实现,需要抛出异常。

安全式组合模式:树叶构件和树枝构件的接口需要区分开来,在实际使用时需要使用者区分构件,对于使用者来说就失去了透明性,但也不会在调用方法时抛出异常。

优点

  1. 使用简单,开发过程也简单。使用者不需要关心整体和单个对象的区别。
  2. 清晰地划分了对象的职责。
  3. 符合开放封闭原则。想要加新的对象,只需要实现统一的接口即可,不需要修改已有的代码。

缺点

  1. 有一定的设计难度。需要理清对象间的层级关系,才能够设计出相应的类。
  2. 随着对象的种类越来越多,整体的结构会变得复杂。

原则

“+”代表遵守,“-”代表不遵守或者不相关

原则 开放封闭 单一职责 迪米特 里氏替换 依赖倒置 接口隔离 合成复用
+ + + +

适用场景(动机)

  1. 希望整体对象和单个对象间在使用上没有差别。
  2. 希望整体对象呈现树形结构

具体的一些使用场景:菜单、文件夹。

如何实现

想要实现组合模式,需要有以下三样东西:

  1. 抽象构件(接口/抽象类):作为声明树叶构件和树枝构件的公共接口,定义树叶和树枝的默认行为。如果是安全式组合模式的话就需要有两个抽象接口。
  2. 树叶构件:需要实现抽象构件,树叶构件没有子节点。
  3. 树枝构件:需要实现抽象构件,树枝构件有子节点,负责存储和管理子节点。

下面举例在学校中的统计人数,一个学校需要统计人数,就会把任务交给每个年级的年级主任,年级主任再向班长去要人数,最后就有班长来统计人数,然后年级主任再相加,再交给上级。

从这里我们也可以看出这是一个树型的结构,在具体的使用中也会用到递归。

上类图

image-20210601153712645

才想起来IDEA可以写完代码后就可以查看类之间的关系了,亏我之前还自己去画类图,所以我现在已经写完代码了,来粘上我的代码。

哭..

上代码

抽象构件:Component

/**
 *
 * 抽象构件
 * Created on 2021/6/1.
 *
 * @author xuxiaobai
 */
public interface Component {

    int sum();
}

复制代码

树枝构件:Composite

/**
 * 年级主任
 * 树枝构件
 * Created on 2021/6/1.
 *
 * @author xuxiaobai
 */
public class Composite implements Component{

    /**年级班长的集合
    * 这里建议使用声明的公共接口,这样就能够添加多种对象
    * 需要指定特俗的对象时,可以使用对象作为声明
    */
    List<Component> leafs=new ArrayList<>();
    //加入新的班长
    public void add(Component component){
        leafs.add(component);
    }

    /**
     * 统计总人数
     * @return
     */
    @Override
    public int sum() {
        int sum=0;
        for (Component leaf : leafs) {
            sum+=leaf.sum();
        }
        return sum;
    }
}
复制代码

树叶构件:Leaf

/**
 * 班长
 * 树叶构件
 * Created on 2021/6/1.
 *
 * @author xuxiaobai
 */
public class Leaf implements Component {
    private int num;
    public Leaf(int num){
        this.num=num;
    }

    @Override
    public int sum() {
        return num;
    }
}
复制代码

测试类:

/**
 * 组合模式测试类
 * Created on 2021/6/1.
 *
 * @author xuxiaobai
 */
public class CompositeTest {
    public static void main(String[] args) {
        Composite composite = new Composite();
        composite.add(new Leaf(20));
        composite.add(new Leaf(30));
        composite.add(new Leaf(40));

        System.out.println("该年级人数:");
        System.out.println(composite.sum());
        /**
         * 输出结果:
         * 该年级人数:
         * 90
         */
    }
}

复制代码

因为这里的年级主任(树枝构件)和班长(树叶构件)做的事情都是一样的,所有就不存在安全式和透明式一说,如果在多加一些功能,就需要区分出来了。

编程结束

总结

组合模式,又名树形模式,基本上遵守了七大设计原则,是一个非常优秀的设计模式,特别适用于当组合对象呈现出树形结构的情况,在具体实现中的树枝构件和树叶构件可以有多种多样,可以让整个组合对象呈现出非常复杂的结构。但要使用组合模式,需要一定设计经验和能力,理清对象间的层级关系

靓仔的肯定

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享