chapter 8 --模板方法模式
封装算法
1. 模板方法定义了一个算法的步骤,并允许子类为一个或多个步骤提供实现。
模板方法模式:
在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结
构的情况下,重新定义算法中的某些步骤。
Structure
- AbstractClass: 该抽象类包含了模板方法。模板方法在实现算法的过程中,用到了这两个原语操作。模板方法本身和这两个操作的具体实现之间被解耦了。
- ConcreteClass: 具体类实现抽象的操作,当模板方法需要这两个抽象方法时,会调用它们。可能有许多个具体类,每一个都实现了模板方法所需的全部操作。
2. 模板就是一个方法。这个方法将算法定义成一组步骤,其中的任何步骤都可以是抽象的,由子类负责实现。这可以确保算法的结构保持不变,同时由子类提供部分实现。
abstract class AbstractClass { final void templateMethod() { primitiveOperation1(); primitiveOperation2(); concreteOperation(); hook(); } abstract void primitiveOperation1(); abstract void primitiveOperation2(); final void concreteOperation() {... } void hook() {}
- templateMethod是模板方法,它被声明为final,以免子类改变这个算法的顺序。
- 模板方法定义了一连串的步骤,每个步骤由一个方法代表。
- 抽象方法由子类实现。
- 具体方法被定义在抽象类中。将它声明为final,使得子类无法覆盖它。它可以被模板方法直接使用,或者被子类使用。
- 有一个“默认不做事的方法”,称为hook。子类可以视情况决定要不要覆盖它们。
钩子
钩子是一种被声明在抽象类中的方法,但只有空的或者默认的实现。钩子的存在,可以让子类有能力对算法的不同点进行挂钩。要不要挂钩由子类自行决定。为了使用钩子,通常在子类中覆盖它。
3. 钩子可以作为条件控制,影响抽象类中的算法流程。当你的子类“必须”提供算法中某个方法或者步骤的实现时,就使用抽象方法。如果算法的这个部分是可选的,就用钩子。这样,子类可以选择实现这个钩子,减轻抽象类的子类的负荷。
设计原则:
(1) 别调用我们,我们会调用你。(好莱坞原则)
该原则允许低层组件将自己挂钩到系统上,但是高层组件会决定什么时候和怎样使用这些低层组件。
4. 具体的applet大量使用钩子来提供行为。因为这些行为是作为钩子实现的,所以Applet类就不用去实现它们。
常见用途:
创建框架,Arrays.sort,Swing,applet。
本章小结:
- 模板方法定义了算法的步骤,把这些步骤的实现延迟到子类。
- 模板方法模式为我们提供了一种代码复用的重要技巧。
- 模板方法的抽象类可以定义具体方法、抽象方法和钩子。
- 抽象方法由子类实现。
- 钩子是一种方法,它在抽象类中不做事,或者只做默认的事情,子类可以选择要不要去覆盖它。
- 为了防止子类改变模板方法中的算法,可以将模板方法声明为final。
- 好莱坞原则告诉我们,将决策权放在高层模块中,以便决定如何以及何时调用低层模块。
- 你将在真实世界代码中看到模板方法模式的许多变体,不要期待它们全都是一眼就可以被你认出的。
- 策略模式和模板方法模式都封装算法,一个用组合,一个用继承。
- 工厂方法是模板方法的一个特殊版本。