模闆方法模式是類的行為模式。準備一個抽象類,将部分邏輯以具體方法以及具體構造函數的形式實作,然後聲明一些抽象方法來迫使子類實作餘下的邏輯。不同的子類可以以不同的方式實作這些抽象方法,進而對剩餘的邏輯有不同的實作。這就是模闆方法模式的用意。 (學習)
模闆方法模式的結構
模闆方法模式是所有模式中最為常見的幾個模式之一,是基于繼承的代碼複用的基本技術。
模闆方法模式需要開發抽象類和具體子類的設計師之間的協作。一個設計師負責給出一個算法的輪廓和架構,另一些設計師則負責給出這個算法的各個邏輯步驟。代表這些具體邏輯步驟的方法稱做基本方法(primitive method);而将這些基本方法彙總起來的方法叫做模闆方法(template method),這個設計模式的名字就是從此而來。
模闆方法所代表的行為稱為頂級行為,其邏輯稱為頂級邏輯。模闆方法模式的靜态結構圖如下所示:
這裡涉及到兩個角色:
抽象模闆(Abstract Template)角色有如下責任:
- 定義了一個或多個抽象操作,以便讓子類實作。這些抽象操作叫做基本操作,它們是一個項級邏輯的組成步驟。
- 定義并實作了一個模闆方法。這個模闆方法一般是一個具體方法,它給出了一個頂級邏輯的架構,而邏輯的組成步驟在相應的抽象操作中,推遲到子類實作。頂級邏輯也有可能調用一些具體方法。
具體模闆(Concrete Template)角色有如下責任:
- 實作父類所定義的一個或多個抽象方法,它們是一個頂級邏輯的組成步驟。
- 每一個抽象模闆角色都可以有任意多個具體模闆角色與之對應,而每一個具體模闆角色都可以組出這些抽象方法(也就是頂級邏輯的組成步驟)的不同實作,進而使得頂級邏輯的實作各不相同。
源代碼
抽象模闆角色類,AbstractMethod(),HoodMethod()等基本方法是頂級邏輯的組成步驟,這個頂級邏輯由TemplateMethod()方法代表。
package TemplateMethod
/**
* 模闆方法模式
* */
abstract class AbstractTemplate {
/**
* 模闆方法
* */
fun templateMethod() {
//調用基本方法
abstractMethod()
hookMethod()
concreteMethod()
}
/**
* 基本方法的聲明,由子類實作
* */
protected abstract fun abstractMethod()
/**
* 基本方法,空方法,子類可重寫此方法
* */
open fun hookMethod(){
}
/**
* 基本方法,已實作
* */
private fun concreteMethod(){
//相關代碼
}
}
具體模闆角色類,實作了父類所聲明的基本方法,AbstractMethod()方法所代表的就是強制子類實作的乘餘邏輯,而hookMethod()方法是可選擇實作的邏輯,不是必要實作的。
package TemplateMethod
class ConcreteTemplate : AbstractTemplate() {
/**
* 基本方法的實作
* */
override fun abstractMethod() {
//業務相關代碼
}
/**
* 重寫父類的方法
* */
override
fun hookMethod() {
//相關業務代碼
}
}
模闆模式的關鍵是:子類可以置換掉父類的可變部分,但是子類卻不可以改奕模闆方式所代表的頂級邏輯。
每當定義一個新的子類時,不要按照控制流程的思路去想,而應當按照“責任”的思路去想。換言之,應當考慮哪些操作是必順置換掉的,哪些操作是可以置換掉的,以及哪些操作是不可以換掉的。使用模闆模式可以使這些責任變得清晰。