模板方法模式在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模版方法是的子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
类图
(图片源于网络)
代码实现(Java)
// CaffeineBeverage.javapublic abstract class CaffeineBeverage { final void prepareRecipe() { boilWater(); brew(); pourInCup(); addCondiments(); } abstract void brew(); abstract void addCondiments(); void boilWater() { System.out.println("Boiling water"); } void pourInCup() { System.out.println("Pouring into cup"); }}
// CaffeineBeverageWithHook.javapublic abstract class CaffeineBeverageWithHook { void prepareRecipe() { boilWater(); brew(); pourInCup(); if (customerWantsCondiments()) { addCondiments(); } } abstract void brew(); abstract void addCondiments(); void boilWater() { System.out.println("Boiling water"); } void pourInCup() { System.out.println("Pouring into cup"); } boolean customerWantsCondiments() { return true; }}
// Coffee.javapublic class Coffee extends CaffeineBeverage { public void brew() { System.out.println("Dripping Coffee through filter"); } public void addCondiments() { System.out.println("Adding Sugar and Milk"); }}
// CoffeeWithHook.javapublic class CoffeeWithHook extends CaffeineBeverageWithHook { public void brew() { System.out.println("Dripping Coffee through filter"); } public void addCondiments() { System.out.println("Adding Sugar and Milk"); } public boolean customerWantsCondiments() { String answer = getUserInput(); if (answer.toLowerCase().startsWith("y")) { return true; } else { return false; } } private String getUserInput() { String answer = null; System.out.print("Would you like milk and sugar with your coffee (y/n)? "); BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); try { answer = in.readLine(); } catch (IOException ioe) { System.err.println("IO error trying to read your answer"); } if (answer == null) { return "no"; } return answer; }}
// Tea.javapublic class Tea extends CaffeineBeverage { public void brew() { System.out.println("Steeping the tea"); } public void addCondiments() { System.out.println("Adding Lemon"); }}
// TeaWithHook.javapublic class TeaWithHook extends CaffeineBeverageWithHook { public void brew() { System.out.println("Steeping the tea"); } public void addCondiments() { System.out.println("Adding Lemon"); } public boolean customerWantsCondiments() { String answer = getUserInput(); if (answer.toLowerCase().startsWith("y")) { return true; } else { return false; } } private String getUserInput() { // get the user's response String answer = null; System.out.print("Would you like lemon with your tea (y/n)? "); BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); try { answer = in.readLine(); } catch (IOException ioe) { System.err.println("IO error trying to read your answer"); } if (answer == null) { return "no"; } return answer; }}
测试代码
// BeverageTestDrive.javapublic class BeverageTestDrive { public static void main(String[] args) { Tea tea = new Tea(); Coffee coffee = new Coffee(); System.out.println("\nMaking tea..."); tea.prepareRecipe(); System.out.println("\nMaking coffee..."); coffee.prepareRecipe(); TeaWithHook teaHook = new TeaWithHook(); CoffeeWithHook coffeeHook = new CoffeeWithHook(); System.out.println("\nMaking tea..."); teaHook.prepareRecipe(); System.out.println("\nMaking coffee..."); coffeeHook.prepareRecipe(); }}
运行效果