模板方法模式:在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中,模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
模板就是一个方法,这个方法将算法定义成一组步骤,其中的任何步骤都可以是抽象的,由子类负责实现。
例子:泡茶和泡咖啡:
类CaffeineBeverageWithHook
public 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("Boiling water");
}
boolean customerWantsCondiments(){
return true;
}
}
类CoffeeWithHook:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public 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;
}
}
类TeaWithHook:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class TeaWithHook extends CaffeineBeverageWithHook{
public void brew()
{
System.out.println("Dripping tea through filter");
}
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(){
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;
}
}
测试:
public class BeverageTestDrive {
public static void main(String[] args)
{
CaffeineBeverageWithHook teaHook = new TeaWithHook();
CaffeineBeverageWithHook coffeeHook = new CoffeeWithHook();
System.out.println("\n making tea...");
teaHook.prepareRecipe();
System.out.println("\n making coffee...");
coffeeHook.prepareRecipe();
}
}
钩子是一种被申明在抽象类中的方法,但只有空的或者默认的实现。钩子的存在,可以让子类有能力对算法的不同点进行挂钩。
Hook Method:提供缺省的实现,子类可以在必要时进行扩展,钩子简化了子类的实现,它可以让子类能够有机会对模板方法中某些即将发生的(或刚刚发生的)步骤做出反应