.NET?設(shè)計(jì)模式之模板方法模式(Template?Method?Pattern)詳解
簡(jiǎn)介
模板方法模式(Template Method Pattern),又叫模板模式(Template Pattern),是一種行為設(shè)計(jì)模式,它定義了一個(gè)操作中的算法框架,將某些步驟的具體實(shí)現(xiàn)留給子類(lèi)。通過(guò)模板方法模式,我們可以在不改變算法結(jié)構(gòu)的情況下,允許子類(lèi)重新定義某些步驟,從而實(shí)現(xiàn)代碼復(fù)用和擴(kuò)展。
在軟件開(kāi)發(fā)中,我們經(jīng)常會(huì)遇到需要定義一組相似操作的場(chǎng)景。這些操作可能在整體上有著相同的結(jié)構(gòu),但在細(xì)節(jié)上有所差異。如果每次都重復(fù)編寫(xiě)這些操作的通用結(jié)構(gòu),會(huì)導(dǎo)致代碼的冗余性,同時(shí)也增加了后期維護(hù)的難度。為了解決這個(gè)問(wèn)題,模板方法模式應(yīng)運(yùn)而生。
角色
- 抽象類(lèi)(Abstract Class):抽象類(lèi)定義了算法的框架,包括一個(gè)或多個(gè)抽象方法和具體方法。其中的抽象方法由子類(lèi)實(shí)現(xiàn),具體方法可以被子類(lèi)直接繼承或重寫(xiě)。
- 具體子類(lèi)(Concrete Subclass):具體子類(lèi)繼承抽象類(lèi),并根據(jù)需要實(shí)現(xiàn)其中的抽象方法。具體子類(lèi)提供了算法的具體實(shí)現(xiàn)細(xì)節(jié)。
優(yōu)點(diǎn)
- 代碼復(fù)用:模板方法模式通過(guò)將算法的通用結(jié)構(gòu)定義在抽象類(lèi)中,可以使子類(lèi)直接繼承這些通用部分,從而達(dá)到代碼復(fù)用的目的。
- 擴(kuò)展性:模板方法模式允許子類(lèi)根據(jù)需要重寫(xiě)父類(lèi)的某些步驟,從而實(shí)現(xiàn)對(duì)算法的自由擴(kuò)展和修改,同時(shí)保持整體結(jié)構(gòu)的穩(wěn)定性。
- 封裝性:模板方法模式將算法的實(shí)現(xiàn)細(xì)節(jié)封裝在抽象類(lèi)中,對(duì)調(diào)用者屏蔽了具體的實(shí)現(xiàn)細(xì)節(jié),只暴露出高層接口。
缺點(diǎn)
- 模板方法模式將算法的執(zhí)行流程固定在抽象類(lèi)中,可能會(huì)導(dǎo)致代碼的可讀性降低,增加理解和維護(hù)的難度。
- 模板方法中的步驟越多, 其維護(hù)工作就可能會(huì)越困難。
- 通過(guò)子類(lèi)抑制默認(rèn)步驟實(shí)現(xiàn)可能會(huì)導(dǎo)致違反里氏替換原則。
應(yīng)用場(chǎng)景
- 當(dāng)存在一組相似的操作,它們具有相同的算法結(jié)構(gòu),但實(shí)現(xiàn)細(xì)節(jié)各不相同時(shí)。
- 當(dāng)希望在不改變算法的整體結(jié)構(gòu)的情況下,允許子類(lèi)自由擴(kuò)展或修改某些步驟時(shí)。
- 當(dāng)希望將算法的實(shí)現(xiàn)細(xì)節(jié)封裝起來(lái),只暴露出高層接口供調(diào)用者使用時(shí)。
實(shí)現(xiàn)
- 定義一個(gè)抽象類(lèi)或接口作為基類(lèi),其中包含模板方法以及一些抽象方法或虛方法
public abstract class TemplateMethodPattern { // 模板方法 public final void TemplateMethod() { Console.WriteLine("執(zhí)行固定步驟1..."); ConcreteMethod(); // 調(diào)用抽象方法或虛方法 Console.WriteLine("執(zhí)行固定步驟2..."); } // 抽象方法或虛方法,子類(lèi)需要實(shí)現(xiàn)這些方法以提供具體邏輯 protected abstract void ConcreteMethod(); }
創(chuàng)建具體的子類(lèi)并實(shí)現(xiàn)抽象方法或虛方法
public class ConcreteClassA : TemplateMethodPattern{ // 實(shí)現(xiàn)抽象方法或虛方法 protected override void ConcreteMethod() { Console.WriteLine("子類(lèi)A的具體實(shí)現(xiàn)步驟..."); }} public class ConcreteClassB : TemplateMethodPattern{ protected override void ConcreteMethod() { Console.WriteLine("子類(lèi)B的具體實(shí)現(xiàn)步驟..."); }}
上層應(yīng)用調(diào)用
class Program{ static void Main(string[] args) { ConcreteClassA concreteClassA = new ConcreteClassA(); concreteClassA.TemplateMethod(); // 輸出固定步驟和子類(lèi)A的具體實(shí)現(xiàn)步驟 ConcreteClassB concreteClassB = new ConcreteClassB(); concreteClassB.TemplateMethod(); // 輸出固定步驟和子類(lèi)B的具體實(shí)現(xiàn)步驟 }}
在這個(gè)案例中,TemplateMethodPattern
類(lèi)定義了一個(gè)模板方法 TemplateMethod
,它包含了一些固定的步驟以及一個(gè)抽象方法 ConcreteMethod
。子類(lèi) ConcreteClassA
和 ConcreteClassB
分別實(shí)現(xiàn)了 ConcreteMethod
方法以提供它們自己的具體邏輯。當(dāng)調(diào)用 TemplateMethod
時(shí),固定的步驟會(huì)執(zhí)行,然后調(diào)用子類(lèi)提供的具體實(shí)現(xiàn)。這樣,你就可以確保算法的某些步驟始終被執(zhí)行,同時(shí)允許子類(lèi)根據(jù)需要提供額外的實(shí)現(xiàn)。
關(guān)注博主即可閱讀全文 優(yōu)惠劵
相關(guān)文章
讀寫(xiě)xml所有節(jié)點(diǎn)個(gè)人小結(jié) 和 讀取xml節(jié)點(diǎn)的數(shù)據(jù)總結(jié)
讀寫(xiě)xml所有節(jié)點(diǎn)個(gè)人小結(jié) 和 讀取xml節(jié)點(diǎn)的數(shù)據(jù)總結(jié)...2007-03-03ASP.NET Cookie 操作實(shí)現(xiàn)
本節(jié)中的主題描述如何在 ASP.NET Web 應(yīng)用程序中創(chuàng)建 Cookie。Cookie 是一些小的文本文件,服務(wù)器和瀏覽器在收到每個(gè)頁(yè)請(qǐng)求時(shí)交換它們,您還可以使用這些小文本文件來(lái)存儲(chǔ)幫助針對(duì)每個(gè)用戶(hù)自定義您的應(yīng)用程序的信息。2009-11-11Asp.Net類(lèi)庫(kù)中發(fā)送電子郵件的代碼
發(fā)送電子郵件是許多需要用戶(hù)注冊(cè)的網(wǎng)站的通用功能,通過(guò)正則表達(dá)式我們可以過(guò)濾掉不符合電子郵件格式的輸入,但是仍沒(méi)有辦法確保用戶(hù)填寫(xiě)的電子郵件地址一定是他本人真實(shí)有效的電子郵件地址2008-09-09Asp.net在線備份、壓縮和修復(fù)Access數(shù)據(jù)庫(kù)示例代碼
這篇文章主要介紹了Asp.net如何在線備份、壓縮和修復(fù)Access數(shù)據(jù)庫(kù),需要的朋友可以參考下2014-03-03使用HtmlAgilityPack XPath 表達(dá)式抓取博客園數(shù)據(jù)的實(shí)現(xiàn)代碼
使用HtmlAgilityPack XPath表達(dá)式來(lái)抓取博客園數(shù)據(jù)使用WebClient 下載數(shù)據(jù),HtmlAgilityPack XPath表達(dá)式解析數(shù)據(jù),并綁定到Repeater控件2011-12-12