設計模式 模板模式

2021-12-29 20:43:48 字數 2852 閱讀 7096

一、引子

這是乙個很簡單的模式,卻被非常廣泛的使用。之所以簡單是因為在這個模式中僅僅使

用到了繼承關係。

繼承關係由於自身的缺陷,被專家們扣上了「罪惡」的帽子。「使用委派關係代替繼承關

系」,「盡量使用介面實現而不是抽象類繼承」等等專家警告,讓我們這些菜鳥對繼承「另眼相

看」。    其實,繼承還是有很多自身的優點所在。只是被大家濫用的似乎缺點更加明顯了。合理

的利用繼承關係,還是能對你的系統設計起到很好的作用的。而模板方法模式就是其中的一

個使用範例。

二、定義與結構

模板方法(template method)模式:定義乙個操作中的演算法的骨架,而將一些步驟延

遲到子類中。使得子類可以不改變乙個演算法的結構即可重定義該演算法的某些特定步驟。這裡

的演算法的結構,可以理解為你根據需求設計出來的業務流程。特定的步驟就是指那些可能在

內容上存在變數的環節。

可以看出來,模板方法模式也是為了巧妙解決變化對系統帶來的影響而設計的。使用模

板方法使系統擴充套件性增強,最小化了變化對系統的影響。這一點,在下面的舉例中可以很明

顯的看出來。

來看下這個簡單模式的結構吧:

1)  抽象類(abstract class):定義了一到多個的抽象方法,以供具體的子類來實現它們;

而且還要實現乙個模板方法,來定義乙個演算法的骨架。該模板方法不僅呼叫前面的抽象

方法,也可以呼叫其他的操作,只要能完成自身的使命。

2)  具體類(concrete class):實現父類中的抽象方法以完成演算法中與特定子類相關的步驟。

下面是模板方法模式的結構圖。直接把《設計模式》上的圖拿過來用下:

三、舉例

還是在我剛剛分析完原始碼的junit 中找個例子吧。junit 中的testcase 以及它的子類就

是乙個模板方法模式的例子。在testcase 這個抽象類中將整個測試的流程設定好了,比如

先執行setup 方法初始化測試前提,在執行測試方法,然後再teardown 來取消測試設定。

但是你將在setup、teardown 裡面作些什麼呢?鬼才知道呢!!因此,而這些步驟的具體實

現都延遲到子類中去,也就是你實現的測試類中。

來看下相關的源**吧。

這是testcase 中,執行測試的模板方法。你可以看到,裡面正像前面定義中所說的那

樣,它制定了「演算法」的框架——先執行setup 方法來做下初始化,然後執行測試方法,最

後執行teardown 釋放你得到的資源。

public void runbare() throws throwable

finally

}這就是上面使用的兩個方法。與定義中不同的是,這兩個方法並沒有被實現為抽象方法,

而是兩個空的無為方法(被稱為鉤子方法)。這是因為在測試中,我們並不是必須要讓測試

程式使用這兩個方法來初始化和釋放資源的。如果是抽象方法,則子類們必須給它乙個實現,

不管用到用不到。這顯然是不合理的。使用鉤子方法,則你在需要的時候,可以在子類中重

寫這些方法。

protected void setup() throws exception

protected void teardown() throws exception

四、適用情況

根據上面對定義的分析,以及例子的說明,可以看出模板方法適用於以下情況:

1)  一次性實現乙個演算法的不變的部分,並將可變的行為留給子類來實現。

2)  各子類中公共的行為應被提取出來並集中到乙個公共父類中以避免**重複。其實這可

以說是一種好的編碼習慣了。

3)  控制子類擴充套件。模板方法只在特定點呼叫操作,這樣就只允許在這些點進行擴充套件。比如

上面runbare  ()方法就只在runtest 前面適用setup 方法。如果你不願子類來修改你

的模板方法定義的框架,你可以採用兩種方式來做:一是在api 中不體現出你的模板方

法;或者將你的模板方法置為final 就可以了。

可以看出,使用模板方法模式可以將**的公共行為提取出來,達到復用的目的。而且,

在模板方法模式中,是由父類的模板方法來控制子類中的具體實現。這樣你在實現子類的時

候,根本不需要對業務流程有太多的了解。

深入淺出設計模式-中文版

1、模板方法模式包括哪些角色以及角色的作用?

答:模板方法模式包括兩種角色:抽象模板和具體模板。

抽象模板(abstract template)角色:

抽象模板是乙個抽象類。抽象模板定義了若干個方法以表示乙個演算法的各個步驟,這些方法中有抽象方法也有非抽象方法,其中的抽象方法稱作原語操作。重要的一點是,抽象模板中還定義了乙個稱作模板方法的方法,該方法不僅包含有抽象模板中表示演算法步驟的方法呼叫,而且也可以包含有定義在抽象模板中的其他物件的方法呼叫,即模板方法定義了演算法的骨架。

具體模版(concrete template)角色:

具體模板是抽象模板的子類,實現抽象模板中的原語操作。

2、模板方法的優缺點。

答:優點:可以通過在抽象模板定義模板方法給出成熟的演算法步驟,同時又不限制步驟的細節,具體模板實現演算法細節不會改變整個演算法的骨架。在抽象模板模式中,可以通過鉤子方法對某些步驟進行掛鉤,具體模板通過鉤子可以選擇演算法骨架中的某些步驟。在子類定義詳細的處理演算法時不會改變演算法的結構,實現了**的復用,通過對子類的擴充套件可以增加新的行為,符合「開閉原則」。

缺點:每個不同的實現都需要定義乙個子類,這也會導致類的個數的增加,系統更加龐大,設計也更加抽象,但是更加符合「單一職責原則」,使得類的內聚性得以提高。

3、適合模板方法模式的情景有哪些?

答:設計者需要給出乙個演算法的固定步驟,並將某些步驟的具體實現留給子類來實現;

需要對**進行重構,將各個子類公共行為提取出來集中到乙個共同的父類中以避免**重複。

模板設計模式 設計模式 模板方法模式

在模板模式 template pattern 中,乙個抽象類公開定義了執行它的方法的方式 模板。它的子類可以按需要重寫方法實現,但呼叫將以抽象類中定義的方式進行。這種型別的設計模式屬於行為型模式。首先需要一定抽象的定義,沒有具體的實現,但是在抽象類的行為中,子類去程序這個抽象類,重寫抽象方法,實現不...

模板設計模式 設計模式之模板模式

模板模式,通常又叫做模板方法模式,乙個抽象類公開定義了執行方法的模板,它的子類可以按需要重寫方法實現,但呼叫將以抽象類中定義的方法進行,這種型別的設計模式屬於行為型模式。模板模式主要解決將通用的演算法抽象起來,同樣的 邏輯出現了重複,就可以使用模板模式進行重構。關鍵 在抽象類實現,其他步驟在子類實現...

設計模式 模板設計模式

1 抽象類 abstractclass類中實現了模板方法 template 定義了演算法的骨架,具體子類需要去實現,抽象方法operationr2,3,4 template operationr2,3,4可以是抽象方法,也可以是實現方法 如果是抽象方法,需要到子類實現即可 2 實現類 concret...