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