模板方法模式是全部模式中最爲常見的幾個模式之一,是基於繼承的代碼複用的基本技術。算法
模板方法模式須要開發抽象類和具體子類的設計師之間的協做。一個設計師負責給出一個算法的輪廓和骨架,另外一些設計師則負責給出這個算法的各個邏輯步驟。表明這些具體邏輯步驟的方法稱作基本方法(primitive method);而將這些基本方法彙總起來的方法叫作模板方法(template method),這個設計模式的名字就是今後而來。設計模式
模板方法所表明的行爲稱爲頂級行爲,其邏輯稱爲頂級邏輯。模板方法模式的靜態結構圖以下所示:bash
這裏涉及到兩個角色:ide
抽象模板(Abstract Template)角色有以下責任:spa
定義了一個或多個抽象操做,以便讓子類實現。這些抽象操做叫作基本操做,它們是一個頂級邏輯的組成步驟。設計
定義並實現了一個模板方法。這個模板方法通常是一個具體方法,它給出了一個頂級邏輯的骨架,而邏輯的組成步驟在相應的抽象操做中,推遲到子類實現。頂級邏輯也有可能調用一些具體方法。code
具體模板(Concrete Template)角色又以下責任:cdn
抽象模板角色類,abstractMethod()、hookMethod()等基本方法是頂級邏輯的組成步驟,這個頂級邏輯由templateMethod()方法表明。blog
public abstract class AbstractTemplate {
/**
* 模板方法
*/
public void templateMethod(){
//調用基本方法
abstractMethod();
hookMethod();
concreteMethod();
}
/**
* 基本方法的聲明(由子類實現)
*/
protected abstract void abstractMethod();
/**
* 基本方法(空方法)
*/
protected void hookMethod(){}
/**
* 基本方法(已經實現)
*/
private final void concreteMethod(){
//業務相關的代碼
}
}
複製代碼
具體模板角色類,實現了父類所聲明的基本方法,abstractMethod()方法所表明的就是強制子類實現的剩餘邏輯,而hookMethod()方法是可選擇實現的邏輯,不是必須實現的。繼承
public class ConcreteTemplate extends AbstractTemplate{
//基本方法的實現
@Override
public void abstractMethod() {
//業務相關的代碼
}
//重寫父類的方法
@Override
public void hookMethod() {
//業務相關的代碼
}
}
複製代碼
模板模式的關鍵是:子類能夠置換掉父類的可變部分,可是子類卻不能夠改變模板方法所表明的頂級邏輯。
每當定義一個新的子類時,不要按照控制流程的思路去想,而應當按照「責任」的思路去想。換言之,應當考慮哪些操做是必須置換掉的,哪些操做是能夠置換掉的,以及哪些操做是不能夠置換掉的。使用模板模式可使這些責任變得清晰。
優勢:
缺點:
按照咱們的設計習慣,抽象類負責聲明最抽象、最通常的事情屬性和方法,實現類完成具體的事物屬性和方法。可是模板方法模式卻顛倒了,抽象類定義了部分抽象方法,由子類實現,子類執行結果影響了父類的結果,也就是子類對父類產生了影響,這在複雜的項目中,會帶來代碼閱讀的難度,並且也會讓新手產生不適感
由於引入了一個抽象類,若是具體實現過多的話,須要用戶或開發人員須要花更多的時間去理清類之間的關係。