介紹
在面向對象開發過程中,通常會遇到一個這樣的問題,我們知道一個算法所需的關鍵步驟,并確定了這些步驟的執行順序,但是,某些步驟的具體實現是未知的,或者說某些步驟的實現是會隨著環境的變化而變化的。這類問題的解決方案就是模板方式方法。
定義
定義一個操作中的算法的框架,而將一些步驟延遲到子類中,使得子類可以不改變一個算法的結構即可重定義算法的某些特定步驟。
使用場景
- 多個子類有公有的方法,并且邏輯基本相同
- 重要、復雜的算法,可以把核心算法設計為模板方法,周邊的相關細節功能則有各個子類實現
- 重構時,模板方法模式是一個經常使用的模式,把相同的代碼抽到父類中,然后通過鉤子函數約束其行為。
角色介紹
ABSTemplate 抽象類,定義了一套算法框架,并提供了一個鉤子函數,鉤子函數中按算法框架的邏輯流程調用各步驟方法,鉤子函數是 final 的,保證邏輯流程不能被子類修改,子類只能改變某一步驟中的具體實現,從而保證邏輯流程的穩定性。其中的算法步驟我們稱為模板方法。
ConcreteImpl 具體實現類,負責算法框架各個步驟的具體實現
Android 源碼中的模板方法
在 Android 中,AsyncTask 是一個比較常用的類,這個類就是用了模板方法模式。使用 AsyncTask 時,我們把耗時方法放入 doInBackground 方法中,在 doInBackground 之前,還可以在 onPreExcute 方法中做一些初始化操作,doInBackground 執行完成后,會執行 onPostExcute 方法。而我們只需要構建 AsyncTask 對象,然后執行 execute 方法即可。可以看到整個過程就是一個框架,具體的實現都需要子類來完成,并且執行的算法框架時固定的。
總結
模板方法用 4 個字概括就是,流程封裝。也就是把某個固定的流程封裝到一個 final 函數中,并且讓子類能夠定制這個流程中的某些或所有步驟,這就要求父類提取共用的代碼,提升代碼的復用率,同時也帶來了更好的擴展性。
優點
- 封裝不變代碼,擴展可變部分
- 提取公共代碼部分,便于維護
缺點
模板方法會帶來代碼閱讀的難度,讓用戶覺得難以理解