Template Method 就是定义一个操作中的算法骨架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构可以定义该算法的某些特定步骤 。
简单地说就是 用一些抽象的操作定义一个算法,而子类将重定义这些操作以提供具体的行为。
应用场景
-
一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。
-
各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。
-
控制子类扩展。在父类的模板方法中调用钩子操作,子类可以重定义钩子操作。简单地说就是在父类的模板方法中调用默认方法,子类可以重定义这些默认方法。
钩子操作(hook operation):它提供了缺省的行为,子类可以在必要时进行扩展。一个钩子操作在缺省操作通常是一个空操作。
很重要的一点是模板对象应该指明哪些操作是钩子操作(可以被重定义)以及哪些是抽象操作(必须被重定义)。要幼小的重用一个抽象类,子类编写者必须明确了解哪些操作是设计为有待重定义的。
模式参与者
-
AbstractClass 抽象类
-
定义抽象的原语操作(primitive operation),具体的子类将从定义它们以实现一个算法的各步骤。
-
实现一个模板方法,定义一个算法的骨架,该模板方法不仅调用原语操作,也调用定义在AbstractClass或者其他对象中的操作。
-
-
ConcreteClass 具体类
-
实现原语操作以完成算法中与特定子类相关的步骤。
-
-
ConcreteClass 靠 AbstractClass 来实现算法中不变的步骤。
代码示例
<?php abstract class AbstractClass { // 抽象模板角色 // 模板方法 调用基本方法组装顶层逻辑 public function templateMethod() { $this->primitiveOperation1(); $this->primitiveOperation2(); } // 基本方法 abstract protected function primitiveOperation1(); abstract protected function primitiveOperation2(); } class ConcreteClass extends AbstractClass { // 具体模板角色 protected function primitiveOperation1(){} protected function primitiveOperation2(){} } $class = new ConcreteClass(); $class->templateMethod(); ?>
拓展思路
-
可以使逻辑思路处理通用化
Template Method 优点在于在父类中编写了公共算法,因此无需在每个子类中在编写算法。
-
在Template Method模式中,父类和子类是紧密联系、共同工作的。因此,在子类中实现父类中申明的抽象方法时,必须要理解这些抽象方法被调用的时机。在看不到父类源代码的情况下,想要编写子类是非常困难的。
相关模式
-
Factory Method 模式
Factory Method 模式是将 Template Method 模式用于生成实例的一个典型例子。
-
Strategy 模式
在 Template Method 模式中,可以使用继承改变程序的行为。这是因为 Template Method 模式在父类中定义程序行为的框架,在子类中决定具体的处理。
与此相对的是 Strategy 模式,它可以使用委托改变程序的行为。与 Template Method 模式中改变部分程序行为不同的是,Strategy 模式用于替换整个算法。