意图
实际处理交给子类
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。
为了解决变化对系统带来的影响而设计的,可以是系统扩展性增强。
TemplateMethod使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
适用性
- 一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现
- 各个子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。
- 控制子类扩展。模板方法只在特定点调用“hock”操作,这样就只允许在这些点进行扩展。
- 一次性实现一个算法的不变部分,并将可变的行为留给子类来实现。
- 给子类中公共的行为应被提取出来并集中到一个公共的方法中实现,减少代码重用性
- 控制子类扩展,模板方法只在特点调用操作,这样只允许在这些点进行扩展
结构
参与者
AbstractClass
- 定义抽象的原语操作,具体的子类将重定义它们以实现一个算法的各个步骤。
- 实现一个模板方法,定义一个算法的骨架。该模板方法不仅调用原语操作,也调用定义在AbstractClass或其他对象中的操作。
ConcreteClass
- 实现原语操作以完成算法中与特定子类相关的步骤。
代码
public abstract class AbstractClass {
public abstract void method1();
public final void method2(){
System.out.println("====AbstractClass===method2==");
}
public final void method3(){
System.out.println("====AbstractClass===method3==");
}
public void execute(){
method1();
method2();
method3();
}
}
public class ConcreteClass extends AbstractClass{
public void method1() {
System.out.println("====ConcreteClass===method1==");
}
}
public class Client {
public static void main(String[] args){
AbstractClass abstractClass = new ConcreteClass();
abstractClass.execute();
}
}
协作
ConcreteClass靠AbstractClass来实现算法中不变的步骤。
效果
模板方法是一种代码复用的基本技术。它们在类库中尤为重要,它们提取了类库中的公共行为。
模板方法导致一种反向的控制结构,这种结果有时被称为“好莱坞法则”,即“别找我们,我们找你”。这指的是一个父类调用了一个子类的操作,而不是相反。
模板方法调用下列类型的操作:
1. 具体的操作(ConcreteClass或对客户类的操作)
2. 具体的AbstractClass的操作(即,通常对子类有用的操作)
3. 原语操作(即,抽象操作)
4. Factory Method
5. 钩子操作,它提供了缺省的行为,子类可以在必要时进行扩展,一个钩子操作在缺省操作通常是一个空操作。
很重要的一点是模板方法应该指明哪些操作是钩子操作(可以被重新定义)以及哪些是抽象操作(必须被重定义)。要有效地重用一个抽象类,子类编写者必须明确了解哪些操作是没设计为有待重定义的。
子类可以通过重定义父类的操作扩展该操作的行为,期间可显示地调用父类操作。
不幸的是,人们很容易忘记去调用被继承的行为。我们可以将这样一个操作转换为一个模板方法,以使得父类可以对子类的扩展方法进行控制。也就是,在父类的模板方法中调用钩子操作。子类可以重定义这个钩子操作。
优点
模板方法模式通过把不变的行为搬移到超类,去除子类中的重复代码来体现它的优势。模板方法模式提供了一个很好的代码复用平台。
缺点
采用继承方法的局限性
实现
使用C++访问控制
在C++中,一个模板方法调用的原语操作可以被定义为保护成员。这保证它们只被模板方法调用。并行重定义的原语操作必须定义为虚拟函数。模板方法自身不需要重定义;因此可以将模板方法定义为一个非虚拟成员函数。
尽量减少原语操作
定义模板方法的一个重要目的是尽量减少一个子类具体实现该算法时必须重定义的那些原语操作的数目。需要重定义的操作越多,客户程序就越冗长。
命名约束
可以给被重定义的那些操作的名字加上一个前缀以识别它们。(doGetConnection)
经典例子
Junit中的TestCase
Spring源码中比如JDBCTemplate、HibernateTemplate等,一般在使用模板方法模式的时候,类名上都会有Template标识。
相关模式
Factory Method Pattern
将模板方法模式应用于产生对象实例的典型应用就是工厂方法模式。Factory Method模式常被模板方法调用。
Strategy Pattern
模板方法模式可以使用继承来更改程序,父类中定义好算法架构,具体有子类实现;而策略模式则是采用委托来更改程序,不过策略模式不是修改部分程序而是切换整个算法。模板方法使用继承来改变算法的一部分。Strategy使用委托来改变整个算法。
敬请期待“访问者模式(Visitor Pattern 对象行为型模式)”