深入理解Java設(shè)計模式之模板方法模式
一、什么是模板方法模式
模板方法模式在一個方法中定義一個算法的骨架,而將一些步驟的實現(xiàn)延遲到子類中。模板方法使得子類可以在不改變算法結(jié)構(gòu)的情況下,重新定義算法中某些步驟的具體實現(xiàn)。
看到“設(shè)計模式”這四個字我們往往會覺得高深莫測,但是模板方法模式卻是一個例外,你要關(guān)注的就是一個方法而已。
模板方法模式確實非常簡單,僅僅使用繼承機(jī)制,但是它是一個應(yīng)用非常廣泛的模式。
二、模板方法模式的使用場景
當(dāng)系統(tǒng)中算法的骨架是固定的時候,而算法的實現(xiàn)可能有很多種的時候,就需要使用模板方法模式。
- 多個子類有共有的方法,并且邏輯基本相同
- 重要、復(fù)雜的算法,可以把核心算法設(shè)計為模板方法,周邊的相關(guān)細(xì)節(jié)功能則由各個子類實現(xiàn)
- 重構(gòu)時,模板方法是一個經(jīng)常使用的方法,把相同的代碼抽取到父類中,然后通過構(gòu)造函數(shù)約束其行為。
舉例:需要做一個報表打印程序,用戶規(guī)定需要表頭,正文,表尾。但是客戶的需求會變化,一會希望這樣顯示表頭,一會希望那樣顯示。
這時候采用模板方式就合適。
三、模板方法模式的優(yōu)缺點
優(yōu)點:
封裝不變部分,擴(kuò)展可變部分。把認(rèn)為不變部分的算法封裝到父類中實現(xiàn),而可變部分的則可以通過繼承來繼續(xù)擴(kuò)展。提取公共部分代碼,便于維護(hù)。行為由父類控制,子類實現(xiàn)
缺點:
算法骨架需要改變時需要修改抽象類。
按照設(shè)計習(xí)慣,抽象類負(fù)責(zé)聲明最抽象、最一般的事物屬性和方法,實現(xiàn)類負(fù)責(zé)完成具體的事務(wù)屬性和方法,但是模板方式正好相反,子類執(zhí)行的結(jié)果影響了父類的結(jié)果,會增加代碼閱讀的難度。
四、模板方法模式的實現(xiàn)
AbstractClass
類---抽象模板類,定義并實現(xiàn)了一個模板方法。
這個模板一般是一個具體方法,它給出了一個頂級邏輯的骨架,而邏輯的組成步驟在相應(yīng)的抽象操作中,推遲到子類實現(xiàn)。
頂級邏輯也有可以調(diào)用具體的方法
abstract class AbstractClass { //一些抽象行為放到子類去實現(xiàn) public abstract void PrivateOperation1(); public abstract void PrivateOperation2(); //模板方法,給出了邏輯的骨架,而邏輯的組成是一些相應(yīng)的抽象操作,它們都推遲到子類實現(xiàn) public void TemplateMethod() { PrivateOperation1(); PrivateOperation2(); Console.WriteLine(""); } }
ConcreteClass
類,實現(xiàn)父類所定義的一個或者多個抽象方法。
每一個AbstractClass都可以有任意多個ConcreteClass與之對應(yīng),而每一個ConcreteClass都可以給出這些抽象方法的不同實現(xiàn),從而使得頂級邏輯的實現(xiàn)各不相同。
class ConcreteClassA : AbstractClass { public override void PrivateOperation1() { Console.WriteLine("具體類A方法1實現(xiàn)"); } public override void PrivateOperation2() { Console.WriteLine("具體類A方法2實現(xiàn)"); } } class ConcreteClassB : AbstractClass { public override void PrivateOperation1() { Console.WriteLine("具體類B方法1實現(xiàn)"); } public override void PrivateOperation2() { Console.WriteLine("具體類B方法2實現(xiàn)"); } }
客戶端代碼
static void Main(string[] args) { AbstractClass c; c = new ConcreteClassA(); c.TemplateMethod(); c = new ConcreteClassB(); c.TemplateMethod(); Console.Read(); }
五、總結(jié)
重復(fù)=易錯+難改,模板方法模式是通過父類建立框架,子類在重寫了父類部分方法之后,在調(diào)用從父類繼承的方法,產(chǎn)生不同的效果,通過修改子類,影響父類行為的結(jié)果,模板方法在一些開源框架中應(yīng)用非常多,它提供了一個抽象類,然后開源框架寫了一堆子類,如果需要擴(kuò)展功能,可以繼承此抽象類,然后覆寫protected基本方法,然后在調(diào)用一個類似TemplateMethod()的模板方法,完成擴(kuò)展開發(fā)。
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
springboot vue完成編輯頁面發(fā)送接口請求功能
這篇文章主要為大家介紹了springboot+vue完成編輯頁發(fā)送接口請求功能,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05java線程池參數(shù)位置導(dǎo)致的奪命故障宿主機(jī)打不開
這篇文章主要為大家介紹了java線程池參數(shù)位置導(dǎo)致的奪命故障宿主機(jī)打不開的問題解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06Spring Boot支持Crontab任務(wù)改造的方法
這篇文章主要介紹了Spring Boot支持Crontab任務(wù)改造的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-01-01淺談 java中ArrayList、Vector、LinkedList的區(qū)別聯(lián)系
ArrayList,Vector底層是由數(shù)組實現(xiàn),LinkedList底層是由雙線鏈表實現(xiàn),從底層的實現(xiàn)可以得出性能問題ArrayList,Vector插入速度較慢,查詢速度較快,而LinkedList插入速度較快,而查詢速度較慢。再者由于Vevtor使用了線程安全鎖,所以ArrayList的運行效率高于Vector2015-11-11Java語言之LinkedList和鏈表的實現(xiàn)方法
LinkedList是由傳統(tǒng)的鏈表數(shù)據(jù)結(jié)構(gòu)演變而來的,鏈表是一種基本的數(shù)據(jù)結(jié)構(gòu),它可以動態(tài)地增加或刪除元素,下面這篇文章主要給大家介紹了關(guān)于Java語言之LinkedList和鏈表的實現(xiàn)方法,需要的朋友可以參考下2023-05-05谷歌二維碼引擎com.google.zxing二維碼生成與解析
這篇文章主要給大家介紹了關(guān)于谷歌二維碼引擎com.google.zxing二維碼生成與解析的相關(guān)資料,zxing是google開源的二維碼生成和解析工具,需要的朋友可以參考下2023-07-07