1、定义: 在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中,模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
(为了防止子类改变模板方法中的算法,可以将模板方法声明为final)
2、钩子(hook)是一种方法,它在抽象类中不做事,或者只做默认的事情,子类可以选择要不要去覆盖它。
3、实例:
1)需求:
冲咖啡步骤: 把水煮沸--->用沸水冲泡咖啡--->把咖啡倒进杯子里--->加糖和牛奶
冲茶步骤: 把水煮沸--->用沸水冲泡茶--->把茶倒进杯子里--->加柠檬片
使用模板方法抽取公共类并实现具体动作,子类通过hook覆盖父类中需要的方法。
2)代码实现:
a)抽象父类
public abstract class CaffeineBeverageWithHook { public void prepareRecip(){ boliWater(); brew(); pourInCup(); if(customerWantCondiments()){ addCondiments(); } } abstract void brew(); abstract void addCondiments(); public void boliWater(){ System.out.println("Bolling water"); } public void pourInCup() { System.out.println("Pouring into Cup"); } boolean customerWantCondiments(){ return true; } }
b) 子类具体实现
public class CoffeeWithHook extends CaffeineBeverageWithHook { @Override void brew() { System.out.println("Dripping Coffee through filter"); } @Override void addCondiments() { System.out.println("Adding Suger and Milk"); } public boolean customerWantCondiments() { String answer = getUserInput(); if (answer.toLowerCase().startsWith("y")) { return true; } else { return false; } } private String getUserInput() { String answer = "no"; System.out.println("Would you like some suger and milk (y/n)?: "); BufferedReader in = new BufferedReader(new InputStreamReader((System.in))); try { answer = in.readLine(); } catch (IOException e) { System.out.println("IO error!"); } return answer; } } public class TeaWithHook extends CaffeineBeverageWithHook{ @Override void brew() { System.out.println("Dripping tea through filter"); } @Override void addCondiments() { System.out.println("Adding lemon"); } public boolean customerWantCondiments() { String answer = getUserInput(); if (answer.toLowerCase().startsWith("y")) { return true; } else { return false; } } private String getUserInput() { String answer = "no"; System.out.println("Would you like some lemon (y/n)?: "); BufferedReader in = new BufferedReader(new InputStreamReader((System.in))); try { answer = in.readLine(); } catch (IOException e) { System.out.println("IO error!"); } return answer; } }
c)测试类
public class CaffineBeverageTest { public static void main(String[] args) { TeaWithHook teaHook = new TeaWithHook(); CoffeeWithHook coffeeHook = new CoffeeWithHook(); System.out.println(" ============Making Tea start==========="); teaHook.prepareRecip(); System.out.println(" =============Making Tea end============"); System.out.println(" ============Making Coffee start==========="); coffeeHook.prepareRecip(); System.out.println(" =============Making Coffee end============"); } }
测试结果:
============Making Tea start===========
Bolling water
Dripping tea through filter
Pouring into Cup
Would you like some lemon (y/n)?:
n
=============Making Tea end============
============Making Coffee start===========
Bolling water
Dripping Coffee through filter
Pouring into Cup
Would you like some suger and milk (y/n)?:
y
Adding Suger and Milk
=============Making Coffee end============