简介
模板——字面的意思就是一个固定的东西,模板方法就是说我们根据固定的步骤算法,来丰富这些步骤的行为方式。打个比方:我要建造一个毛胚房,首先我要设计,对于设计,我们可以选择各式各样的设计方案;拿到设计后,我们需要开始建房子,对于不同的设计,我们建造房子的过程也会不一样;同样房子建造好了,我们还需要装修,对于装修的方式我们又可以有多种选择…这里可以看出,我们在设计,建造和装修上都可以进行不同的选择,但是这三个流程是必须经历的过程,所以我们可以将建房子的三个步骤进行固定,即建房子离不开这三个过程且三个过程前后顺序一定。
模板方法(Template Method)模式的定义如下:定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。它是一种类行为型模式。
结构
模板方法模式包含以下主要角色。
抽象类(Abstract Class):负责给出一个算法的轮廓和骨架。它由一个模板方法和若干个基本方法构成。这些方法的定义如下。
具体子类(Concrete Class):实现抽象类中所定义的抽象方法和钩子方法,它们是一个顶级逻辑的一个组成步骤。
示例
模板类:
package com.example.demo.design.templatemethod;
/**
* @author : sun
* create at: 2020/4/28 22:10
* @description: 模板方法——建筑房子
* 这里我说下我对这个模式的理解:父类约束方法行为规范,子类细化每步方法的行为方式
* 注意:父类的约束方法一定要是final,不可更改
* 缺点:因为父类已经约束了行为规范,所有比较死板,不够灵活。
* 优点:可扩展性强;便于维护
*/
public abstract class AbstractHouse {
/**
* 建造房子第一步;拿到设计图纸
*/
public abstract void getDrawing();
/**
* 建筑房子第二步:打地基.开始建房子
*/
public abstract void setGround();
/**
* 建房子第三步:装修
*/
public abstract void decoration();
/**
* 建房子第四步:入住
*/
public abstract void success();
/**
* 规定建造房子的流程
*/
public final void buildHouse(){
getDrawing();
setGround();
decoration();
success();
}
}
实现类一:
package com.example.demo.design.templatemethod;
/**
* @author : sun
* create at: 2020/4/28 22:20
* @description: 我家建房子
*/
public class MyHouse extends AbstractHouse{
@Override
public void getDrawing() {
System.out.println("这是我家房子的设计图纸");
}
@Override
public void setGround() {
System.out.println("我开始打地基了");
}
@Override
public void decoration() {
System.out.println("我家房子建好了,开始装修");
}
@Override
public void success() {
System.out.println("我入住啦");
}
}
实现类二:
package com.example.demo.design.templatemethod;
/**
* @author : sun
* create at: 2020/4/28 22:24
* @description: 他家的房子
*/
public class YouHouse extends AbstractHouse{
@Override
public void getDrawing() {
System.out.println("他家开始设计房子图纸了");
}
@Override
public void setGround() {
System.out.println("他家开始建房子了");
}
@Override
public void decoration() {
System.out.println("他家房子建好开始装修了");
}
@Override
public void success() {
System.out.println("他住进新家了");
}
}
测试类:
package com.example.demo.design.templatemethod;
/**
* @author : sun
* create at: 2020/4/28 22:23
* @description: 测试模板方法设计模式
*/
public class Test {
public static void main(String[] args) {
AbstractHouse house = new MyHouse();
house.buildHouse();
System.out.println("------------------------");
house = new YouHouse();
house.buildHouse();
}
}
应用
对于模板方法的引用场景,个人觉得很简单,如果你在代码开发过程中,发现对于不同情景下代码中出现固定的算法步骤,所以可以将这部分算法步骤抽离出来,让子类来具体实现步骤细节,比如JUC包中的AQS就是按照这种思想来实现的,以及在Spring中的DAO层(JDBC链接)和IOC中都有模板方法的影子,所以这个设计模式的应用是相当广泛的。