模板方法模式
在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。
模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
每一个子类都必须为模板方法中抽象的步骤提供完整的实现
抽象父类中可以使用钩子(hook),让子类决定是否需要执行某些步骤
茶与咖啡
抽象父类
package templateMethod; /** * 模板方法: * 定义了一个算法的步骤 * 允许子类为一个或多个步骤提供实现 */ public abstract class CaffeineBeverage { /** * 主导一切,拥有算法,并且保护整个算法 */ final public void prepare() { boliWater(); brew(); pourInCup(); //使用钩子,能够影响抽象类的算法流程 if(customerWantsCondiments()) { addCondiments(); } } /** * 一个钩子 * 父类中提供缺省的实现 * 子类可以根据需要重写钩子 * 注意:钩子方法不要修饰为private的! */ boolean customerWantsCondiments() { return true; } abstract void brew(); abstract void addCondiments(); void pourInCup() { System.out.println("Pouring into cup"); } void boliWater() { System.out.println("Boiling Water"); } }
具体子类-茶
package templateMethod; public class Tea extends CaffeineBeverage { @Override void brew() { System.out.println("Steeping the tea"); } @Override void addCondiments() { System.out.println("Adding Lemon"); } /** * 覆盖钩子,提供自己的功能 */ boolean customerWantsCondiments() { return false; } }
具体子类-咖啡
package templateMethod; 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"); } }
测试
package test; import templateMethod.CaffeineBeverage; import templateMethod.Coffee; import templateMethod.Tea; public class TemplateMethodTest { public static void main(String[] args) { CaffeineBeverage tea = new Tea(); tea.prepare(); System.out.println("\n==================\n"); CaffeineBeverage coffee = new Coffee(); coffee.prepare(); } }