『设计模式』设计模式--模板方法模式
23種設(shè)計(jì)模式+額外常用設(shè)計(jì)模式匯總 (持續(xù)更新)
簡介
Define the skeleton of an algorithm in an operation,deferring some
steps to subclasses.Template Method lets subclasses redefine certain
steps of an algorithm without changing the algorithm’s structure.
定義一個操作中的算法的框架,而將一些步驟延遲到子類中。使得子類可以不改變一個算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟。
-----------------------------------------------------------------深入淺出的設(shè)計(jì)模式
-
模板方法模式(Template Method Pattern) 實(shí)際上是封裝了一個固定流程,該流程由幾個步驟組成,具體步驟可以由子類進(jìn)行不同實(shí)現(xiàn),從而讓固定的流程產(chǎn)生不同的結(jié)果。
-
意圖:定義一個操作中的算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以不改變一個算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟。
-
模板方法模式實(shí)際上是所有模式中最為常見的幾個模式之一,而且很多人可能使用過模板方法模式而沒有意識到自己已經(jīng)使用了這個模式。模板方法模式是基于繼承的代碼復(fù)用的基本技術(shù),模板方法模式的結(jié)構(gòu)和用法也是面向?qū)ο笤O(shè)計(jì)的核心。模板方法的本質(zhì):抽象封裝流程,具體進(jìn)行實(shí)現(xiàn)
-
模版方法模式需要開發(fā)抽象類和具體子類的設(shè)計(jì)師之間的協(xié)作。
- 一個設(shè)計(jì)師負(fù)責(zé)給出一個算法的輪廓和骨架
- 另一些設(shè)計(jì)師則負(fù)責(zé)給出這個算法的各個邏輯步驟。
- 代表這些具體邏輯步驟的方法稱做基本方法(primitive method)
- 將這些基本方法總匯起來的方法叫做模版方法(template method),這個設(shè)計(jì)模式的名字就是從此而來。
主要解決
當(dāng)完成一個操作具有固定的流程時(shí),由抽象固定流程步驟,具體步驟交給子類進(jìn)行具體實(shí)現(xiàn)(固定的流程,不同的實(shí)現(xiàn))。
優(yōu)缺點(diǎn)
優(yōu)點(diǎn)
- 封裝不變,擴(kuò)展可變:父類封裝了具體流程以及實(shí)現(xiàn)部分不變行為,其它可變行為交由子類進(jìn)行具體實(shí)現(xiàn);
- 流程由父類控制,子類進(jìn)行實(shí)現(xiàn):框架流程由父類限定,子類無法更改;子類可以針對流程某些步驟進(jìn)行具體實(shí)現(xiàn);
- 提取公共代碼,便于維護(hù)
缺點(diǎn)
- 抽象規(guī)定了行為,具體負(fù)責(zé)實(shí)現(xiàn),與通常事物的行為相反,會帶來理解上的困難(通俗地說,“父類調(diào)用了子類方法”);
- 每一個不同的實(shí)現(xiàn)都需要一個子類來實(shí)現(xiàn),導(dǎo)致類的個數(shù)增加,使得系統(tǒng)更加龐大。
使用場景
當(dāng)我們要完成在某一細(xì)節(jié)層次一致的一個過程或一系列步驟,但其個別步驟在更詳細(xì)的層次上的實(shí)現(xiàn)可能不同的時(shí)候,我們通常要考慮用模板方法模式解決。
- 多個子類有公有的方法,并且邏輯基本相同時(shí);
- 重要,復(fù)雜的算法,可以把核心算法設(shè)計(jì)為模板方法,周邊的相關(guān)細(xì)節(jié)功能則由各個子類實(shí)現(xiàn);
- 重構(gòu)時(shí),模板方法模式 是一個經(jīng)常使用的模式,把相同的代碼抽取到父類,然后通過鉤子函數(shù)約束其行為;
注意事項(xiàng): 為防止惡意操作,一般模板方法都加上 final 關(guān)鍵詞。
模式講解
首先來看下 模板方法模式 的通用 UML 類圖:
模板方法模式
從 UML 類圖中,我們可以看到,模板方法模式 主要包含兩種角色:
抽象模板(AbstractClass): 抽象模板類,定義了一套算法框架/流程;
具體實(shí)現(xiàn)(ConcreteClass): 具體實(shí)現(xiàn)類,對算法框架/流程的某些步驟進(jìn)行了實(shí)現(xiàn);
當(dāng)然這只是書面上的定義,用起來你會發(fā)現(xiàn),為什么變得很復(fù)雜,好像更難了一樣,你也有很多疑問?
- 在抽象類中只能定義抽象函數(shù)嗎?
不是!看使用場景第三條! - 每一個抽象子類都要具體實(shí)現(xiàn)嗎?
語法上是的,但邏輯上,可以Do nothing - 依據(jù)第一問,我能否對非抽象方法重寫?
當(dāng)然,語法上可以,而且邏輯上也可以。
最后,設(shè)計(jì)模式給出的是一種設(shè)計(jì)框架,而不是條條框框,你需要用的是他真正優(yōu)秀的地方!
開發(fā)實(shí)例
抽象類:
abstract class AbstractClass {protected void Boil_water() {System.out.println("SpecificMethod:燒水,倒一杯熱水");/** 模板方法的抽象類中,也是可以定義具體方法的, * 一般子類中都具備或大部分中都具備時(shí),放到抽象父類中。*/}// 需要子類必須實(shí)現(xiàn)的需要寫成抽象類protected abstract void Abstract_step1();protected abstract void Abstract_step2();protected void Drink() {System.out.println("SpecificMethod:吹一吹再喝,別燙著!");}// 聲明為final方法,避免子類覆寫public final void After_Tea() {//來一杯下午茶吧this.Boil_water();this.Abstract_step1();this.Abstract_step2();this.Drink();} }我要喝咖啡
class Concrete_Cof extends AbstractClass {@Override// 具體實(shí)現(xiàn),重寫父類抽象方法protected void Abstract_step1() {System.out.println("把咖啡豆磨好,倒進(jìn)杯子里");}@Overrideprotected void Abstract_step2() {System.out.println("加入方糖和奶精");}}我要喝茶
class Concrete_Tea extends AbstractClass {@Overrideprotected void Abstract_step1() {System.out.println("把茶餅分開,放進(jìn)杯子里");}@Overrideprotected void Abstract_step2() {//Do nothing //可以寫成這種什么都沒有的,畢竟喝茶我什么都不加(手動狗頭)}}我要喝奶茶
public class Concrete_MilkTea extends AbstractClass {protected void Boil_water() {System.out.println("煮一杯熱牛奶");}@Overrideprotected void Abstract_step1() {System.out.println("把茶餅分開,放進(jìn)杯子里,過濾");}@Overrideprotected void Abstract_step2() {System.out.println("加入方糖和香精");}} class Client {public static void main(String[] args) {AbstractClass abc = new Concrete_Cof();abc.After_Tea();System.out.println("----------Next day-------------");abc=new Concrete_Tea();abc.After_Tea();System.out.println("----------Next day-------------");abc=new Concrete_MilkTea();abc.After_Tea();} }運(yùn)行結(jié)果:
寫在最后:
我叫風(fēng)骨散人,名字的意思是我多想可以不低頭的自由生活,可現(xiàn)實(shí)卻不是這樣。家境貧寒,總得向這個世界低頭,所以我一直在奮斗,想改變我的命運(yùn)給親人好的生活,希望同樣被生活綁架的你可以通過自己的努力改變現(xiàn)狀,深知成年人的世界里沒有容易二字。目前是一名在校大學(xué)生,預(yù)計(jì)考研,熱愛編程,熱愛技術(shù),喜歡分享,知識無界,希望我的分享可以幫到你!
如果有什么想看的,可以私信我,如果在能力范圍內(nèi),我會發(fā)布相應(yīng)的博文!
感謝大家的閱讀!😘你的點(diǎn)贊、收藏、關(guān)注是對我最大的鼓勵!
總結(jié)
以上是生活随笔為你收集整理的『设计模式』设计模式--模板方法模式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux的mount是什么意思(Lin
- 下一篇: 『设计模式』瑞幸咖啡还是星巴克,一杯下午