定义
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模版方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
结构和说明
示例代码
public class TemplateMethodDemo {
/**
* 定义模版方法,原语操作等的抽象类
*/
public static abstract class AbstractClass {
/**
* 原语操作1,所谓原语操作就是抽象的操作,必须要由子类提供实现
*/
public abstract void doPrimitiveOperation1();
/**
* 原语操作2
*/
public abstract void doPrimitiveOperation2();
/**
* 模版方法,定义算法骨架
*/
public void templateMethod() {
doPrimitiveOperation1();
doPrimitiveOperation2();
}
}
/**
* 具体实现类,实现原语操作
*/
public static class ConcreteClass extends AbstractClass {
@Override
public void doPrimitiveOperation1() {
// 具体实现
}
@Override
public void doPrimitiveOperation2() {
// 具体实现
}
}
}
优缺点
优点
- 实现代码复用
模版方法模式是一种实现代码复用的很好的手段。通过把子类的公共功能提炼和抽取,把公共部分放到模版中去实现。
缺点
- 算法骨架不容易升级
模版方法最基本的功能就是通过模版的制定,把算法骨架完全固定下来。事实上模版和子类是非常耦合的,如果要对模版中的算法骨架进行变更,可能就会要求所有相关的子类进行相应的变化。所以抽取算法骨架的时候要特别小心,尽量确保是不会变化的部分才放到模版中。
思考
本质
固定算法骨架
何时选用
- 需要固定定义算法骨架,实现一个算法的不变的部分,并把可变的行为留给子类来实现的情况。
- 各个子类中具有公共行为,应该抽取出来,集中在一个公共类中去实现,从而避免代码重复。
- 需要控制子类扩展的情况。模版方法模式会在特定的点来调用子类的方法,这样只允许在这些点进行扩展。
相关模式
- 模版方法和工厂方法模式
这两个模式可以配合使用。
模版方法模式可以通过工厂方法来获取需要调用的对象。
- 模版方法和策略模式
这两个模式的功能有些相似,但是是有区别的。
从表面上看,两个模式都能实现算法的封装,但是模版方法封装的是算法的骨架,这个算法骨架是不变的,变化大是算法中某些步骤的具体实现;而策略模式是把某个步骤的具体实现算法封装起来,所有封装的算法对象是等价的,可以相互替换。
因此,可以在模版方法中使用策略模式,就是把那些变化的算法步骤通过策略模式来实现,但是具体选取哪个策略还是要由外部来确定,而整体的算法步骤,也就是算法骨架则由模版方法来定义了。