Android 設計模式 - 模板方法模式
1. 定義
定義一個操作的演算法骨架,而將一些步驟延遲到子類中。模板方法使得子類可以不改變一個演算法的結構,即可重定義該演算法的某些特定步驟。
2. 作用
基於繼承的程式碼複用技術,在模板方法模式中,可以將相同的程式碼放在父類中,而將不同的實現放在子類中。抽象類將部分邏輯以具體方法的形式實現,然後宣告一些抽象方法來讓子類實現剩餘的邏輯。不同的子類以不同的方式實現這些抽象方法,從而對剩餘的邏輯有不同的實現。
3. 結構
-
抽象類
定義模板方法,也就是邏輯的骨架,細化的操作定義成抽象方法由子類實現。
-
具體類
實現抽象類的抽象方法,實現本身的具體操作。
4. 實現
舉個例子:泡茶和衝咖啡。都要經過燒水、放料和沖泡的過程,其中燒水和沖泡是一樣的操作,而放入的原料卻不同。所以,定義一個沖泡熱飲的基本方法:燒水--放料--沖泡,放料定義為抽象方法,由茶和咖啡分別實現。
另外,我們可以決定是否加糖,預設是加糖(甜是大家都愛的嘛),在這裡咖啡需要加糖,而茶卻不需要。所以,茶類可以覆蓋抽象類的預設實現,那麼在泡茶的時候,就不會加糖啦。這個方法稱作鉤子方法,具體類可以通過它來控制抽象類的行為。

類圖
public abstract class CoffeineBeverage { /** * 模板方法,不允許子類覆蓋 */ public final void prepareRecipe() { boilWater(); addCondiment(); brew(); if (isAddSugar()) { System.out.println("加糖"); } } private void boilWater() { System.out.println("燒水"); } private void brew() { System.out.println("沖泡"); } /** * 是否加糖,鉤子方法 * * @return */ protected boolean isAddSugar() { return true; } /** * 加料 */ protected abstract void addCondiment(); }
public class Coffee extends CoffeineBeverage { @Override protected void addCondiment() { System.out.println("加入咖啡"); } } public class Tea extends CoffeineBeverage { @Override protected void addCondiment() { System.out.println("加入茶葉"); } @Override protected boolean isAddSugar() { return false; } }
public static void main(String[] args) { // 衝咖啡 CoffeineBeverage coffee = new Coffee(); coffee.prepareRecipe(); System.out.println("-----------------"); // 泡茶 CoffeineBeverage tea = new Tea(); tea.prepareRecipe(); }
5. 優缺點
1. 優點:
封裝不變部分,擴充套件可變部分,提高了程式碼的複用性;實現了反向的控制結構,父類呼叫其子類的操作,子類的擴充套件增加新的行為,符合「開閉原則」。
2. 缺點:
每個不同的實現都需要定義一個子類,這會導致類的個數增加,系統更加龐大,設計也更加抽象。
3. 使用場景:
- 一次性實現演算法的不變部分,並將可變的行為留給子類來實現。
- 各子類中公共的行為應被提取出來並集中到一個公共父類中以避免程式碼重複。
- 控制子類擴充套件。模板方法只在特定點呼叫“hook”操作 ,這樣就只允許在這些點進行擴充套件。
【附錄】

資料圖