每日設計模式——模板方法模式
阿新 • • 發佈:2018-12-11
模板方法模式
模板方法模式就是定義一個操作中的演算法的框架,而將一些步驟延遲到子類中,使得子類可以不改變一個演算法的結構即可重新定義該演算法的某些特定步驟。
例如:某個特定的應用中具有很多的子任務,每個任務的資料計算步驟幾乎都是一致的,只是具體的實現可能存在一些差別,則可以定義一個超類,在超類中定義所有任務的計算流程,然後子類去實現特殊的步驟。程式碼如下所示:
package com.factory.templetemethod; import java.util.ArrayList; import java.util.List; public class Test { public static void main(String[] args) { SuperApp app1 = new ConcreteApp1(); app1.invoke(); SuperApp app2 = new ConcreteApp2(); app2.invoke(); } } abstract class SuperApp { //基本方法 public abstract List<String> readDataFromDB(); //基本方法 public abstract List<Integer> computeData(List<String> list); //基本方法 public abstract void storeResult(List<Integer> result); //模板方法 public void invoke() { List<String> data = readDataFromDB(); List<Integer> result = computeData(data); storeResult(result); } } class ConcreteApp1 extends SuperApp { public List<String> readDataFromDB() { return null; } public List<Integer> computeData(List<String> list) { System.out.println("ConcreteApp1"); return null; } public void storeResult(List<Integer> result) { } } class ConcreteApp2 extends SuperApp { public List<String> readDataFromDB() { return null; } public List<Integer> computeData(List<String> list) { System.out.println("ConcreteApp2"); return null; } public void storeResult(List<Integer> result) { } }
上述程式碼中,我們在超類SuperApp中定義了任務是計算步驟,分別是
readDataFromDB()
computerData()
storeResult()
這三個操作叫做基本操作,然後定義了一個模板方法
//模板方法 public void invoke() { List<String> data = readDataFromDB(); List<Integer> result = computeData(data); storeResult(result); }
這個方法定義了子類任務的計算步驟。
類圖結構如下所示:
模板方法模式的優點
1. 封裝不變部分,擴充套件可變部分。把認為不變部分的演算法封裝到父類實現,而可變部分的則通過繼承來繼續擴充套件。
2.提取公共部分程式碼,便於維護。
3.行為由父類控制,子類實現。基本方法是由子類實現的,因此子類可以通過擴充套件的方式增加相應的功能,符合開閉原則。
模板方法模式的缺點
按照設計習慣,抽象類負責宣告最抽象,最一般的事物屬性和方法,實現類完成具體的事物屬性和方法。但是模板方法卻顛倒了,抽象類定義了部分抽象方法,由子類實現,子類執行的結果影響了父類的結果,在複雜專案中會帶來程式碼閱讀的難度。
模板方法模式使用場景
1.多個子類有公有的方法,並且邏輯基本相同。
2.重要、複雜的演算法,可以把核心演算法設計成模板方法,周邊的相關細節功能則由各個子類實現。
3.重構時,模板方法模式是一個經常使用的模式,把相同的程式碼抽取到父類中,然後通過鉤子函式約束其行為。