不要將設(shè)計(jì)模式想得高不可攀,好像高手才會(huì)使用的東西,事實(shí)上如果您在下手程式之前,能稍稍對(duì)程式作個(gè)分析規(guī)劃,或多或少都會(huì)用到一些模式了,模式不是教條,它只是前人的經(jīng)驗(yàn)成果,而 Gof 的書則是擇前人之精華持續(xù)改進(jìn)而來(lái)罷了。
Template Method模式就是一個(gè)很簡(jiǎn)單的模式,但可能是使用最廣泛的模式,也許您也一直在使用這樣的模式,看它的 UML 類別結(jié)構(gòu)圖就知道了:
僅僅是抽象類別與具體類別實(shí)作的關(guān)係而已,有些人常問(wèn)抽象類別與介面的區(qū)別為何,Template Method模式可以提供其中一個(gè)答案,例如:
public abstract class AbstractClass {
public void templateMethod() {
// step by step template to solve something
// implementor should follow those step
opStep1();
opStep2();
opStep3();
}
public abstract void opStep1();
public abstract void opStep2();
public abstract void opStep3();
}
public class ConcreteClass extends AbstractClass {
public abstract void opStep1() {
// implement the real operation
}
public abstract void opStep2() {
// implement the real operation
}
public abstract void opStep3() {
// implement the real operation
}
}
對(duì)於一些程式而言,我們希望規(guī)定一些處理的步驟、流程或骨架,就像是上例中的step1到step3一樣,至於流程中的step1到step3如何實(shí)作並不規(guī)定,而留給實(shí)作的人自行決定,這就是Template Method模式的目的。
抽象類別與介面的差別之一,也正在於抽象類別可以先實(shí)作其中一些方法,而介面則是完全僅規(guī)定接口,使用Template Method模式就可以看出兩者之間在應(yīng)用上的一個(gè)差別。
僅以step1到step3這樣的操作來(lái)看Template Method模式,似乎彰顯示不出其實(shí)作骨架,而將實(shí)作部份留待子類的實(shí)用性,在 Gof 書中所舉的例子是與 Factory Method 模式結(jié)合的一個(gè)例子;通常開啟一個(gè)檔案的流程是相似的,例如文字檔或二進(jìn)位檔,不外乎檢查檔案是否可開啟、讀取檔案、設(shè)定顯示等流程,可以使用 Template Method模式來(lái)規(guī)範(fàn)這個(gè)流程:
public abstract class Application {
// .....
public void openDocument(String name) {
// Template Method
if(!canOpenDocument(name)) { // unable to open file
// show error message, throw exception
return;
}
Document doc = createDocument(); // Factory Method
if(doc != null) {
_docs.addDocument(doc);
// Template Method
aboutToOpenDocument(doc);
doc.open();
doc.doRead();
}
}
// Factory Method
public abstract Document createDocument();
// Template Method
public abstract boolean canOpenDocument(String name);
public abstract void aboutToOpenDocument(Document doc);
}
public class MyApplication extends Application {
// implement Factory Method
public void Document createDocument() {
return new MyDocument();
}
// implement Template Method
public void boolean canOpenDocument(String name) {
// implemented code here
}
public void aboutToOpenDocument(Document doc) {
// implemented code here
}
}
Factyro Method模式將實(shí)際要?jiǎng)?chuàng)建的物件推遲至子類中決定,而 Template Method模式則是將流程框架的實(shí)作留待子類來(lái)解決,事實(shí)上在這個(gè)例子中,您也可以將createDocument()看作是Template Method模式中的一個(gè)方法,從物件創(chuàng)建的角度來(lái)看它是Factory Method,而從流程框架的角度來(lái)看,它則是Template Method模式的一個(gè)方法實(shí)作。