5.10-TemplateMethod-模板方法
目的
定义一个操作的算法骨架,而将一些步骤延迟到子类中。通过子类来实现这些步骤,使得不改变算法结构的情况下,可重新定义算法中的某些特定步骤
适用性
- 一次性实现一个算法的不变部分,并将可变的行为留给子类来实现。
- 各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。
- 首先识别现有代码中的不同之处,并且将不同之处分离为新的操作。
- 然后,用一个调用新的操作的模板方法来替换不同的代码。
- 控制子类扩展。模板方法只在特定点调用 hook 操作,这样就只允许在这些点进行扩展。
结构

- AbstractClass:
- 定义抽象的原语操作(primitive operation),具体的子类将重定义它们以实现一个算法的各步骤
- 实现一个模板方法,定义一个算法的骨架。该模板方法不仅调用原语操作,也调用定义在 AbstractClass 或其他对象中的操作。
- ConcreteClass:实现原语操作以完成算法中与特定子类相关的步骤。
效果
模板方法是一种代码复用的基本技术。它们在类库中尤为重要,提取了类库中的公共行为。 模板方法导致一种反向的控制结构,父类调用一个子类的操作。
模板方法调用下列类型的操作:
- 原语操作(即抽象操作):子类必须重载以提供具体实现。
- 钩子操作(hook operation),它提供了缺省的行为,子类可以在必要时通过重载进行扩展。钩子操作在缺省情况下通常是空操作。
- 其他操作:不应重定义这些操作
很重要的一点是模板方法应该区分哪些操作是原语操作(必须重载),哪些是钩子操作(可以重载)
实现
- 访问控制:
- 在 C++中,一个模板方法调用的原语操作可以被定义为 protected 的纯虚函数,保证它们只被模板方法调用,同时必须重载。
- 模板方法自身不需要被重定义,因此可以将模板方法定义为一个非虚成员函数。
- 尽量减少原语操作
- 命名约定:可以给应被重定义的操作的名字加上一个前缀以识别它们
相关模式
Strategy(5.9):模板方法使用继承来改变算法的一部分, Strategy 使用委托来改变整个算法。 Factory Method(3.3)常被模板方法调用。