Template Method模式主要用于封裝如下的程序結構:
initialize();
while(!done()){
idle();
}
cleanUp();
首先進行初始化應用程序。接著進入主循環完成需要做的工作,這些工作或許是GUI事件,或許是處理數據庫記錄。最后,一旦完成了工作,程序就退出主循環,并且在程序終止前做清除工作。
這種結構非常常見,所以可以把它封裝在一個名為Application的類中。之后我們就可以在每個想要編寫的新程序中重用這個類。
以如下將華氏溫度轉換成攝氏溫度程序為例:
package com.pptb.design.patterns.template.method;
import java.util.Scanner;
public class FtoCRaw {
public static void main(String[] args) {
boolean done = false;
while (!done) {
Scanner sc = new Scanner(System.in);
String fahrStr = sc.nextLine();
if (fahrStr == null || fahrStr.length() == 0) {
done = true;
} else {
double fahr = Double.parseDouble(fahrStr);
double celcius = 5.0 / 9.0 * (fahr - 32);
System.out.println("F=" + fahrStr + ",C=" + celcius);
}
}
System.out.println("ftoc exit");
}
}
現在我們使用Template Method模式把這個基本結構從ftoc程序中分離出來。該模式把所有通用代碼放入一個抽象基類的實現方法中。這個實現方法完成了通用算法,但是將所有的實現細節都交付給該基類的抽象方法。
代碼如下:
public abstract class Application {
private boolean isDone = false;
protected abstract void init();
protected abstract void idle();
protected abstract void cleanUp();
protected void setDone() {
this.isDone = true;
}
protected boolean hasDone() {
return this.isDone;
}
public void run() {
this.init();
while (!this.hasDone()) {
this.idle();
}
this.cleanUp();
}
}
然后我們讓剛才的程序通過繼承Application類來改寫ftoc類:
package com.pptb.design.patterns.template.method;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.Scanner;
public class FtoCTemplateMethod extends Application {
private InputStream in;
private PrintStream out;
public static void main(String[] args) {
new FtoCTemplateMethod().run();
}
@Override
protected void init() {
this.in = System.in;
this.out = System.out;
}
@Override
protected void idle() {
Scanner sc = new Scanner(this.in);
String fahrStr = sc.nextLine();
if (fahrStr == null || fahrStr.length() == 0) {
this.setDone();
} else {
double fahr = Double.parseDouble(fahrStr);
double celcius = 5.0 / 9.0 * (fahr - 32);
this.out.println("F=" + fahrStr + ",C=" + celcius);
}
}
@Override
protected void cleanUp() {
this.out.println("ftoc exit");
}
}
Template Method模式展示了面向對象編程中諸多經典重用形式中的一種。其中通用算法被放置在基類中,并且通過繼承在不同的具體上下文中實現通用算法。
但是這項技術是有代價的。繼承是一種非常強的關系。派生類不可避免地要和它們的基類綁定在一起。