组合模式及其在JDK源码中的运用
设计模式系列总览
设计模式 | 飞机票 |
---|---|
三大工厂模式 | 登机入口 |
策略模式 | 登机入口 |
委派模式 | 登机入口 |
模板方法模式 | 登机入口 |
观察者模式 | 登机入口 |
单例模式 | 登机入口 |
原型模式 | 登机入口 |
代理模式 | 登机入口 |
装饰者模式 | 登机入口 |
适配器模式 | 登机入口 |
建造者模式 | 登机入口 |
责任链模式 | 登机入口 |
享元模式 | 登机入口 |
组合模式 | 登机入口 |
门面模式 | 登机入口 |
桥接模式 | 登机入口 |
中介者模式 | 登机入口 |
迭代器模式 | 登机入口 |
状态模式 | 登机入口 |
解释器模式 | 登机入口 |
备忘录模式 | 登机入口 |
命令模式 | 登机入口 |
访问者模式 | 登机入口 |
软件设计7大原则和设计模式总结 | 登机入口 |
前言
本文主要会讲述组合模式的用法,并会结合在JDK和MyBatis源码中的运用来进一步理解组合模式。
在编码原则中,有一条是:多用组合,少用继承。当然这里的组合和我们今天要讲的组合模式并不等价,这里的组合其实就是一种聚合,那么聚合和组合有什么区别呢?
组合和聚合
人在一起叫团伙,心在一起叫团队。用这句话来诠释组合与聚合的区别是相对恰当的。
聚合就是说各个对象聚合在一起工作,但是我没有你也行,我照样可以正常运行。但是组合呢,关系就比较密切,组合中的各个对象之间组成了一个整体,缺少了某一个对象就不能正常运行或者说功能会有很大缺陷。
也就是说聚合对象不具备相同生命周期,而组合的对象具有相同的生命周期
举个例子:
比如说电脑和U盘就是聚合,而电脑显示器和主机就是组合。
什么是组合模式
组合模式(Composite Pattern)也称之为整体-部分(Part-Whole)模式。组合模式的核心是通过将单个对象(叶子节点)和组合对象(树枝节点)用相同的接口进行表示,使得单个对象和组合对象的使用具有一致性。组合模式属于结构型模式。
组合模式一般用来描述整体与部分的关系,它将对象组织到树形结构中,最顶层的节点称为根节点,根节点下面可以包含树枝节点和叶子节点,树枝节点下面又可以包含树枝节点和叶子节点如下图所示:
讲了这么多,感觉有点抽象,所以依然是老规矩:Talk is cheap,Show you the code。
示例
组合模式有两种写法,分别是透明模式和安全模式。下面我们就以高考的科目为例来看看组合模式是如何体现在代码中的
透明组合模式
1、首先建立一个顶层的抽象科目类,这个类中定义了三个通用操作方法,但是均默认不支持操作
package com.zwx.design.pattern.composite.transparency;
/**
* 顶层抽象组件
*/
public abstract class GkAbstractCourse {
public void addChild(GkAbstractCourse course){
System.out.println("不支持添加操作");
}
public String getName() throws Exception {
throw new Exception("不支持获取名称");
}
public void info() throws Exception{
throw new Exception("不支持查询信息操作");
}
}
PS:这个类是抽象类,但是在这里并没有将这些方法定义为抽象方法,而是默认都抛出异常。这么做的原因是假如定义为抽象方法,那么所有的子类都必须重写父类方法。但是这种通过抛异常的方式,如果子类需要用到的功能就重写覆盖父类方法即可,不需要用到的方法直接无需重写。
2、新建一个普通科目类继承通用科目抽象类,这个类作为叶子节点,没有重写addChild方法,也就是这个类属于叶子节点,不支持添加子节点:
package com.zwx.design.pattern.composite.transparency;
/**
* 普通科目类(叶子节点)
*/
public class CommonCource extends GkAbstractCourse {
private String name;//课程名称
private String score;//课程分数
public CommonCource(String name, String score) {
this.name = name;
this.score = score;
}
@Override
public String getName