行为型模式--Template Method模式(模板方法)类行为型模式
一. 意图
定义一个操作中的算法的骨架, 而将一些步骤延迟到子类中. TemplateMethod使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤.
通过使用抽象操作定义一个算法中的一些步骤, 模板方法确定了它们的先后顺序.
二. 适用性
1. 各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复. 这是Opdyke和Johnsn所描述过的"重分解以一般化"的一个很好的例子[OJ93]. 首先识别现有代码中的不同之处, 并且将不同之处分离为新的操作. 最后, 用一个调用这些新的操作的模板方法来替换这些不同的代码.
2. 控制子类扩展. 板方法只在特定点调用"hook"操作, 这样就只允许在这些点进行扩展.
三. 模式结构
图1
一次性实现一个算法的不变的部分, 并将可变的行为留给子类来实现.
四. 角色说明
AbstractClass(抽象类)
—定义抽象的原语操作(primitive operation), 具体的子类将重定义它们以实现一个算法
-实现一个模板方法, 定义一个算法的骨架. 该模板方法不仅调用原语操作, 也调用定义在AbstractClass或其他对象中的操作.
ConcreteClass(具体类)
—实现原语操作以完成算法中与特定子类相关的步骤.
五. 说明
1. 模板方法是一种代码复用的基本技术. 它们在类库中尤为重要, 它们提取了类库中的公共行为. 模板方法导致一种反向的控制结构, 这种结构有时被称为"好莱坞法则", 即"别找我们, 我们找你"[Swe85]. 这指的是一个父类调用一个子类的操作, 而不是相反.
2. 模板方法调用下列类型的操作:
-具体的操作(ConcreteClass或对客户类的操作).
-具体的AbstractClass的操作(即, 通常对子类有用的操作).
-原语操作(即抽象操作).
-Factory Method.
-钩子操作, 它提供了缺省的行为, 子类可以在必要时进行扩展。一个钩子操作在缺省操作通常是一个空操作.(可重载的, 非抽象的)
3. 很重要的一点是模板方法应该指明哪些操作是钩子操作(可以被重定义)以及哪些是抽象操作(必须被重定义). 要有效地重用一个抽象类, 子类编写者必须明确了解哪些操作是设计为有待重定义的.子类可以通过重定义父类的操作来扩展该操作的行为, 其间可显式地调用父类操作.
六. 我的理解
1. 从Template Method模式的结构图看到, 把固定的部分实现在父类的TemplateMethod()方法中, 把可扩展的放在可重载的方法中, 扩展时使用子类来扩展.
2. 对比Strategy模式, 也和Template Method一样有固定的部分, 也有扩展的部分, Strategy模式把扩展部分分配到各个Strategy子类中, 而且使用的不是继承, 而是包含.
3. Template Method模式适合实现一些框架. 框架在TemplateMethod中固定好, 框架的用户根据框架的结构要求, 重载对应的需要扩展的方法.
4. Template Method实现框架是使用了继承, 这种继承关系在程序运行前已经固定好的, 而Strategy模式的思想也可以实现框架, 它使用的包含, 更灵活.
5. State模式也和Strategy模式相似. 个人认为这两种方式也是符合"Don't call me, I'll call you"的原则. Template Method模式, State模式, Strategy模式这3中模式在这点上思想是很相似的.
七. 相关模式
Factory Method模式常被模板方法调用.
模板方法使用继承来改变算法的一部分. Strategy使用委托来改变整个算法.