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









































圖4
示意性實(shí)現(xiàn)代碼:











































































再來(lái)看看客戶(hù)端程序的調(diào)用,不需要再去調(diào)用每一個(gè)步驟的方法:

























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
































































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

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