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============