模板方法( Template Method )模式:定義一個操作中的算法的骨架,而將一些步驟延遲到子類中。 Template Method 使得子類可以不改變一個算法的結構即可重定義該算法的某些特定步驟。

適用性:

  • 一次性實現一個算法的不變的部分,并將可變的行為留給子類來實現。
  • 各子類中公共的行為應被提取出來并集中到一個公共父類中以避免代碼重復。首先識別現有代碼中的不同之處,并且將不同之處分離為新的操作。最后,用一個調用這些新的操作的模板方法來替換這些不同的代碼。
  • 控制子類擴展。模板方法只在特定點調用“hook”操作,這樣就只允許在這些點進行擴展。

template.bmp

涉及到的角色:

?? 抽象模板 (Abstract Template) 角色: 1 。定義一個或者多個抽象操作,以便讓子類實現,這些抽象操作叫做基本操作,它們是一個頂級邏輯的組成步驟。 2 。定義并實現一個模板方法,這個模板方法一般是具體方法,它給出了頂級邏輯的骨架,而邏輯的組成步驟在相應的抽象操作中,推遲到子類中實現,頂級邏輯也可能調用一些具體方法。

?? 具體模板 (Concrete Template) 角色:實現父類所定義的一個或多個抽象方法,它是頂級邏輯的的組成步驟。每一個抽象模板角色都可以有任意多個具體模板角色與之相對應,而每一個具體模板角色都可以給出這些抽象方法的不同實現,從而使得頂級邏輯的實現各不相同。

一個具體的例子:
抽象模板:

package ?TemplateMethod;

public ? abstract ? class ?Account {
????
protected ?String?accountNumber;
????
// 默認構造方法
???? public ?Account() {
????????accountNumber
= null ;
????}

????
// 構造方法
???? public ?Account(String?accountNumber) {
????????
this .accountNumber = accountNumber;
????}

????
// 模板方法???設計利息數額
???? final ? public ? double ?calculateInterest() {
????????
double ?interestRate = doCalculateInterest();
????????String?accountType
= doCalculateAccountType();
????????
double ?amount = calculateAmount(accountType,accountNumber);
????????
return ?amount * ?interestRate;
????}

????
// 基本方法留給子類實現
???? protected ? abstract ? double ?doCalculateInterest();
????
// 基本方法留給子類實現
???? protected ? abstract ?String?doCalculateAccountType();
????
// 基本方法,已經實現
???? protected ? double ?calculateAmount(String?accountType,String?accountNumber) {
????????
// 一些操作
???????? return ? 7243.00D ;
????}

????
}

具體模板:

package ?TemplateMethod;

public ? class ?MoneyMarketAccount? extends ?Account {
????
// 基本方法,在這里實現
???? public ? double ?doCalculateInterest() {
????????
return ? 0.045D ;
????}

????
// 基本方法,在這里實現
???? public ?String?doCalculateAccountType() {
????????
return ? " Money?Market " ;
????}

}

package ?TemplateMethod;

public ? class ??CDMarket? extends ?Account {
????
// 基本方法,在這里實現
???? public ? double ?doCalculateInterest() {
????????
return ? 0.065D ;
????}

????
// 基本方法,在這里實現
???? public ?String?doCalculateAccountType() {
????????
return ? " Certificate?of?Deposite " ;
????}

}

?客戶端類:

package ?TemplateMethod;

public ? class ?Client {
????
private ? static ?Account?acc = null ;
????
????
public ? static ? void ?main(String[]?args) {
????????acc
= new ?MoneyMarketAccount();
????????System.out.println(
" Interest?from?Money?Market: " + acc.calculateInterest());
????????acc
= new ?CDMarket();
????????System.out.println(
" Interest?form?Certificate?of?Deposite: " + acc.calculateInterest());
????}

}


參考資料:
《java與模式》
《設計模式速查找手冊》