摘要:Template Method模式是比較簡單的設計模式之一,但它卻是代碼復用的一項基本的技術,在類庫中尤其重要。
主要內容
1
.概述
2
.Template Method解說
3
..NET中的Template Method模式
4
.適用性及實現要點
概述
變化一直以來都是軟件設計的永恒話題,在XP編程中提倡擁抱變化,積極應對。如何更好的去抓住變化點,應對變化?如何更好的提高代碼復用?通過學習Template Method模式,您應該有一個新的認識。
意圖
定義一個操作中的算法的骨架,而將一些步驟延遲到子類中。Template Method使得子類可以不改變一個算法的結構即可重定義該算法的某些特定步驟。[-GOF《設計模式》]
結構圖
圖1Template Method 模式結構圖
生活中的例子
模板方法定義了一個操作中算法的骨架,而將一些步驟延遲到子類中。房屋建筑師在開發新項目時會使用模板方法。一個典型的規劃包括一些建筑平面圖,每個平面圖體現了不同部分。在一個平面圖中,地基、結構、上下水和走線對于每個房間都是一樣的。只有在建筑的后期才開始有差別而產生了不同的房屋樣式。
圖2使用建筑圖為例子的Template Method模式
Template Method
模式解說
李建忠
老師說過一句話,如果你只想掌握一種設計模式的話,那這個模式一定是Template Method模式。對于這個問題,我想可能是仁者見仁,智者見智,但是有一點不能否認的Template Method模式是非常簡單而且幾乎是無處不用,很少有人沒有用過它。下面我們以一個簡單的數據庫查詢的例子來說明Template Method模式(注意:這個例子在實際數據庫開發中并沒有任何實際意義,這里僅僅是為了作為示例而已)。
假如我們需要簡單的讀取Northwind數據庫中的表的記錄并顯示出來。對于數據庫操作,我們知道不管讀取的是哪張表,它一般都應該經過如下這樣的幾步:
1
.連接數據庫(Connect)
2
.執行查詢命令(Select)
3
.顯示數據(Display)
4
.斷開數據庫連接(Disconnect)
這些步驟是固定的,但是對于每一張具體的數據表所執行的查詢卻是不一樣的。顯然這需要一個抽象角色,給出頂級行為的實現。如下圖:
圖3
Template Method
模式的實現方法是從上到下,我們首先給出頂級框架DataAccessObject的實現邏輯:









































圖4
示意性實現代碼:











































































再來看看客戶端程序的調用,不需要再去調用每一個步驟的方法:

























在上面的例子中,需要注意的是:
1
.對于Connect()和Disconnect()方法實現為了virtual,而Select()和Display()方法則為abstract,這是因為如果這個方法有默認的實現,則實現為virtual,否則為abstract。
2
.Run()方法作為一個模版方法,它的一個重要特征是:在基類里定義,而且不能夠被派生類更改。有時候它是私有方法(private method),但實際上它經常被聲明為protected。它通過調用其它的基類方法(覆寫過的)來工作,但它經常是作為初始化過程的一部分被調用的,這樣就沒必要讓客戶端程序員能夠直接調用它了。
3
.在一開始我們提到了不管讀的是哪張數據表,它們都有共同的操作步驟,即共同點。因此可以說Template Method模式的一個特征就是剝離共同點。
.NET
中的Template Method模式
.NET Framework
中Template Method模式的使用可以說是無處不在,比如說我們需要自定義一個文本控件,會讓它繼承于RichTextBox,并重寫其中部分事件,如下例所示:
































































其中OnSelectionChanged()和OnTextChanged()便是Template Method模式中的基本方法之一,也就是子步驟方法,它們的調用已經在RichTextBox中實現了。
實現要點
1
.Template Method模式是一種非常基礎性的設計模式,在面向對象系統中有著大量的應用。它用最簡潔的機制(虛函數的多態性)為很多應用程序框架提供了靈活的擴展點,是代碼復用方面的基本實現結構。
2
.除了可以靈活應對子步驟的變化外,“不用調用我,讓我來調用你”的反向控制結構是Template Method的典型應用。
3
.在具體實現方面,被Template Method調用的虛方法可以具有實現,也可以沒有任何實現(抽象方法,純虛方法),但一般推薦將它們設置為protected方法。[李建忠]
適用性
1
.一次性實現一個算法的不變的部分,并將可變的行為留給子類來實現。
2
.各子類中公共的行為應被提取出來并集中到一個公共父類中以避免代碼重復。這是Opdyke和Johnson所描述過的“重分解以一般化”的一個很好的例子。首先識別現有代碼中的不同之處,并且將不同之處分離為新的操作。最后,用一個調用這些新的操作的模板方法來替換這些不同的代碼。
3
.控制子類擴展。模板方法只在特定點調用“Hook”操作,這樣就只允許在這些點進行擴展。
總結
Template Method
模式是非常簡單的一種設計模式,但它卻是代碼復用的一項基本的技術,在類庫中尤其重要。
本篇文章寫的比較簡單,請大家見諒。更多的設計模式文章可以訪問《
.NET設計模式系列文章
》
參考資料
Erich Gamma
等,《設計模式:可復用面向對象軟件的基礎》,機械工業出版社
Robert C.Martin
,《敏捷軟件開發:原則、模式與實踐》,清華大學出版社
閻宏,《Java與模式》,電子工業出版社
Alan Shalloway James R. Trott
,《Design Patterns Explained》,中國電力出版社
MSDN WebCast
《C#面向對象設計模式縱橫談(14):Template Method模版方法模式(結構型模式)》
顯然在這個頂級的框架DataAccessObject中給出了固定的輪廓,方法Run()便是模版方法,Template Method模式也由此而得名。而對于Select()和Display()這兩個抽象方法則留給具體的子類去實現,如下圖:
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
