|
無(wú)處不在的Template Method
如果你只想掌握一種設(shè)計(jì)模式,那么它就是
-----Template Method!
變與不變
變化——是軟件設(shè)計(jì)的永恒主題,如何管理變化帶來(lái)的復(fù)雜性?設(shè)計(jì)模式的藝術(shù)性和復(fù)雜度就在于如何分析,并發(fā)現(xiàn)系統(tǒng)中的變化點(diǎn)和穩(wěn)定點(diǎn),并使用特定的設(shè)計(jì)方法來(lái)應(yīng)對(duì)這種變化。
動(dòng)機(jī)(Motivation)
在軟件構(gòu)建過(guò)程中,對(duì)于某一項(xiàng)任務(wù),它常常有穩(wěn)定的整體操作結(jié)構(gòu),但各個(gè)子步驟卻有很多改變的需求,或者由于固有的原因(比如框架與應(yīng)用之間的關(guān)系)而無(wú)法和任務(wù)的整體結(jié)構(gòu)同時(shí)實(shí)現(xiàn)。如何在確定穩(wěn)定操作結(jié)構(gòu)的前提下,來(lái)靈活應(yīng)對(duì)各個(gè)子步驟的變化或者晚期實(shí)現(xiàn)需求?
意圖(Intent)
定義一個(gè)操作中的算法的骨架,而將一些步驟延遲到子類中。Template Method使得子類可以不改變一個(gè)算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟。
——《設(shè)計(jì)模式》GoF
例說(shuō)Template Method應(yīng)用
下面是汽車測(cè)試軟件的例子
具體實(shí)現(xiàn)
客戶程序
這里new的地方可以根據(jù)需要用創(chuàng)建型的設(shè)計(jì)模式來(lái)設(shè)計(jì)。
這里我們把抽象類里面的抽象方法寫(xiě)為了public,我建議對(duì)于虛方法或者抽象方法,一般寫(xiě)為protected;對(duì)于非虛的方法或者非抽象的方法,才寫(xiě)為public。因?yàn)槿绻枪械奶摲椒ǎ蛽?dān)當(dāng)了兩個(gè)不同方面的責(zé)任。只要設(shè)置了一個(gè)虛方法,那就意味著這是一個(gè)擴(kuò)展點(diǎn)。如果是public方法,也就是客戶程序可以直接訪問(wèn)這個(gè)函數(shù),但是虛方法是不具有外界訪問(wèn)的資質(zhì)的。因此我們推薦虛方法都用protected來(lái)修飾。
結(jié)構(gòu)(Structure)
AbstractClass對(duì)應(yīng)例子中的Vehicle抽象類,TemplateMethod對(duì)應(yīng)例子中的Test方法,PrimitiveOperation等虛方法對(duì)應(yīng)Startup、Run等虛方法,ConcreteClass對(duì)應(yīng)HongqiCar具體類。
Template Method模式的幾個(gè)要點(diǎn)
Template Method模式是一種非?;A(chǔ)性的設(shè)計(jì)模式,在面向?qū)ο笙到y(tǒng)中有著大量的應(yīng)用。它用最簡(jiǎn)潔的機(jī)制(虛函數(shù)的多態(tài)性)為很多應(yīng)用程序框架提供了靈活的擴(kuò)展,是代碼復(fù)用方面的基本實(shí)現(xiàn)結(jié)構(gòu)。除了可以靈活應(yīng)對(duì)子步驟的變化外,“Don't call me, let me call you(不要調(diào)用我,讓我來(lái)調(diào)用你)”的反向控制結(jié)構(gòu)是Template Method的典型應(yīng)用。
在具體實(shí)現(xiàn)方面,被Template Method調(diào)用的虛方法可以具有實(shí)現(xiàn),也可以沒(méi)有任何實(shí)現(xiàn)(抽象方法、純虛方法),但一般推薦將它們?cè)O(shè)置為protected方法。
.NET架構(gòu)中的Template Method應(yīng)用
一個(gè)簡(jiǎn)單的Windows窗體應(yīng)用
這里OnPaint是一個(gè)虛方法的子步驟,這就是一個(gè)Template Method設(shè)計(jì)模式。如果我們不去重寫(xiě)這個(gè)OnPaint方法,它就有一個(gè)基本的默認(rèn)實(shí)現(xiàn),畫(huà)一個(gè)空窗體。這里我們并沒(méi)有調(diào)用OnPaint方法,而是Application的Run會(huì)進(jìn)入Windows的消息循環(huán)結(jié)構(gòu),Paint就是一個(gè)消息。當(dāng)我們移動(dòng)一下窗口都會(huì)導(dǎo)致Paint事件的發(fā)生,并導(dǎo)致OnPaint函數(shù)的調(diào)用,這就是一種反向調(diào)用。當(dāng)然,還有很多其他的子步驟可以提供擴(kuò)展點(diǎn),例如OnClose等,很多以O(shè)n開(kāi)頭的全部都是Template Method模式的虛方法。
這個(gè)里面內(nèi)容很復(fù)雜,它并不是用一個(gè)Template Method在里面調(diào)用所有的子步驟方法,它實(shí)際上是把整體的Template Method方法置于了一個(gè)消息循環(huán)的結(jié)構(gòu)里面,我們可以把消息循環(huán)的結(jié)構(gòu)看做模板方法里面的TemplateMethod公有非虛方法。
it知識(shí)庫(kù):C#面向?qū)ο笤O(shè)計(jì)模式縱橫談:Template Method 模板方法,轉(zhuǎn)載需保留來(lái)源!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。