1、动机
在软件构建过程中,对于某一项任务,它常常有稳定的整体操作结构,但各个子步骤却有很多改变的需求,或者由于固有的原因(比如框架于应用之间的关系)需求无法和任务的整体结构同时实现。
如何在确定稳定操作结构的前提下,来灵活应对各个子步骤的的变化或者晚期实现的需求?
2、场景
如某个业务需要步骤一、步骤二、步骤三、步骤四、步骤五 五个步骤完成,但是步骤一三四是固定不会变化的,步骤二五有多种变化方式。
(1)实现方式一
方案一:接口(或抽象类)定义步骤一二三四五的方法,并实现一三四的方法,方法的实现和步骤的掌控交给实现类(或子类)
public class TemplateMethod {
/**
* 类库实现者开发
*/
interface Lib {
default void step1() {
//实现
}
/**
* 变化
*/
void step2();
default void step3() {
//实现
}
default void step4() {
//实现
}
/**
* 变化
*/
void step5();
}
/**
* 客户端
*/
class Client implements Lib {
@Override
public void step2() {
//实现
}
@Override
public void step5() {
//实现
}
/**
* 需求
*/
public void demand() {
//控制步骤
step1();
step2();
step3();
step3();
step4();
step5();
}
}
}
缺点: 客户端使用者把控稳定的步骤一至步骤五的操作,容易提高代码出错的概率;当变化多的时候,demand()方法复用率低(其次,你也可以抽方法,虽然有更好的复用方式)
(2)实现方式二(模板方法模式)
public class TemplateMethod {
/**
* 类库实现者开发
*/
interface Lib {
default void step1() {
//实现
}
//变化-->多态
void step2();
default void step3() {
//实现
}
default void step4() {
//实现
}
/**
* 变化-->多态
*/
void step5();
/**
* 整体结构(模板方法模式)
*/
default void demand(){
step1();
step2();
step3();
step3();
step4();
step5();
}
}
public static void main(String[] args) {
Lib lib = new Lib() {
@Override
public void step2() {
//实现
}
@Override
public void step5() {
//实现
}
};
lib.demand();
}
}
3、概念
定义一个操作中的算法的骨架,而将一些变化的步骤延迟到子类中,TemplateMethod使得子类可以不改变一个算法的结构,直接可重写算法的某些特定步骤来应对这个步骤的变化。