模板方法模式的定義
模板方法模式(Template Method Pattern)是如此簡單,以致讓你感覺你已經能夠掌握其精髓了。其定義如下:
Define the skeleton of an algorithm in an operation, deferring some steps to subclasses.Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure. (定義一個操作中的算法的框架,而將—些步驟延遲到子類中。使得子米可以不改變一個算法的結構即可重定義該算法的某些特定步驟。)
通用類圖如下:
模板方法模式確實非常簡單,僅僅使用了Java的繼承機制,但它是一個應用非常廣泛的模式。其中,AbstractClass 叫做抽象模板,它的方法分為兩類:基本方法基本方法也叫做基本操作,是由子類實現的方法,并且在模板方法被調用。口模板方法可以有一個或幾個,一般是一個具體方法,也就是一個框架,實現對基本方法的調度,完成固定的邏輯。
模板方法模式的應用
模板方法模式的優點
封裝不變部分,擴展可變部分把認為是不變部分的算法封裝到父類實現,而可變部分的則可以通過繼承來繼續擴展。
提取公共部分代碼,便于維護
行為由父類控制,子類實現基本方法是由子類實現的,因此子類可以通過擴展的方式增加相應的功能,符合開閉原則。
模板方法模式的缺點
按照我們的設計習慣,抽象類負責聲明最抽象、最一般的事物屬性和方法,實現類完成具體的事物屬性和方法。但是模板方法模式卻顛倒了,抽象類定義了部分抽象方法,由子類實現,子類執行的結果影響了父類的結果,也就是子類對父類產生了影響,這在復雜的項目中,會帶來代碼閱讀的難度,而且也會讓新手產生不適感。
模板方法模式的使用場景
多個子類有公有的方法,并且邏輯基本相同時。重要、復雜的算法,可以把核心算法設計為模板方法,周邊的相關細節功能則由各個子類實現。
重構時,模板方法模式是一個經常使用的模式,把相同的代碼抽取到父類中,然后通過勾子函數約束其行為。
最佳實踐
初級程序員在寫程序的時候經常會問高手“父類怎么調用子類的方法”。這個問題很有普遍性,反正我是被問過好幾回,那么父類是否可以調用子類的方法呢?我的回答是能,但極度地不建議這么做。
父類建立框架,子類在重寫了父類部分的方法后,再調用從父類繼承的方法,產生不同的結果(而這正是模板方法模式)。這是不是也可以理解為父類調用了子類的方法呢?你修改了子類,影響了父類行為的結果,曲救國的方式實現了父類依賴子類的場景,模板方法模式就是這種效果。
模板方法在一些開源框架中應用非常多,它提供了一個抽象類,然后開源框架寫了一堆子類。在《x In Action》中就說明了,如果你需要擴展功能,可以繼承這個抽象類,然后覆寫protected方法,再然后就是調用一個類似execute方法,就完成你的擴展開發,非常容易擴展的一種模式。