模板方法模式:
定义:
在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
例子:
包含模板方法的类
package factory.templetpattern; public abstract class CaffeineBeverage { final void prepareRecipe(){ boilWater(); brew(); pourInCup(); if (needCondiments()) { addCondiments(); } } abstract void brew(); abstract void addCondiments(); void boilWater(){ System.out.println("Boiling water"); } void pourInCup(){ System.out.println("Pouring into cup"); } /** 钩子 (hook) */ abstract boolean needCondiments(); }
具体实现类
package factory.templetpattern; public class Coffee extends CaffeineBeverage{ @Override void brew() { System.out.println("Dripping coffee through filter"); } @Override void addCondiments() { System.out.println("Adding Sugar and Milk"); } @Override boolean needCondiments() { return true; } }
package factory.templetpattern; public class Tea extends CaffeineBeverage{ void brew(){ System.out.println("Steeping the tea"); } void addCondiments(){ System.out.println("Addling lemon"); } @Override boolean needCondiments() { return false; } }
主函数
public class BeverageTestDrive { public static void main(String[] args){ Tea tee = new Tea(); System.out.println("\n make tea"); tee.prepareRecipe(); Coffee coffee = new Coffee(); System.out.println("\n make coffee"); coffee.prepareRecipe(); } }
结果:
make tea Boiling water Steeping the tea Pouring into cup make coffee Boiling water Dripping coffee through filter Pouring into cup Adding Sugar and Milk
总结
- 模板方法为我们提供了一种代码复用的重要技巧。
- 模板方法的抽象类可以定义具体方法、抽象方法和钩子。
- 钩子是一种方法,它在抽象类中不做事,或者只做默认的事情,子类可以选择要不要去覆盖他。
通过钩子可以使子类有能力为抽象类做一些决定。
- 为了防止子类改变模板方法中的算法,可以将模板方法声明为final。
- 好莱坞原则告诉我们,将决策权放在高层模块中,以便决定如何以及何时调用底层模块。
- 策略模式和模板方法模式都封装算法,一个用组合,一个用继承。
- 工厂方法是模板方法的一种特殊版本。