动机(Motivation)
在软件构件过程中,对于某一项任务,它常常有稳定的整体操作结构,但各个子步骤却又很多改变的需求,或者由于固有的原因(比如框架与应用之间的关系)而无法和任务的整体结构同时实现。
如何在确定稳定操作结构的前提下,来灵活应对各个子步骤的变化或者晚期实现需求?
意图(Intent)
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
结构
基本方法:也叫基本操作,是由子类实现的方法,并且在模板方法中被调用。 模板方法:可以有一个或几个,一般是一个具体方法,也就是一个框架,实现对基本方法的调度,完成固定的逻辑。
为了防止恶意的操作,一般模板方法都加上final关键字,不允许被覆写。
使用场景
- 多个子类有公有的方法,并且逻辑基本相同时。
- 重要、复杂的算法,可以把核心算法设计为模板方法,周边的相关细节功能则由各个子类实现。
模板方法的几个要点
-
Template Method模式是一种非常基础性的设计模式,在面向对象系统中有着大量的应用。它用最简洁的机制(抽象方法的多态)为很多应用程序框架提供了灵活的扩展点,是代码复用方面的基本实现结构。
-
除了可以灵活应对子步骤的变化外,“不要调用我,让我来调用你”的反向控制结构是Template Method的典型应用。
-
再具体实现方面,被Template Method调用的方法可以具有实现,也可以没有任何实现(抽象方法),但一般推荐将他们设置为protected方法。
示例代码
抽象模板类:
public abstract class AbstractClass{
//基本方法,用protected修饰
protected abstract void doSomething();
protected abstract void doAnything();
// 模板方法,用public修饰
public void templateMethod(){
this.doAnything();
this.doSomething();
}
}
具体模板类:
public class ConcreteClass extends AbstractClass{
protected abstract void doSomething(){}
protected abstract void doAnything(){}
}
场景类:
public class Client{
public static void main(Stirng[] args){
ConcreteClass clazz = new ConcreteClass();
clazz.templateMethod();
}
}