軟體設計模式學習(二十六)模板方法模式

来源:https://www.cnblogs.com/Yee-Q/archive/2020/06/17/13152550.html

模板方法是結構最簡單的行為型設計模式,在抽象類中定義了一個稱為模板方法的方法,在這個方法中定義其他基本方法的執行步驟,而基本方法的實現可以放在抽象類,也可以放在其子類 模式動機 現實生活中很多事情的完成過程都包含幾個基本步驟,例如請客吃飯,無論吃什麼,一般都包含點單、吃東西、買單幾個步驟,到底吃什麼 ...



模板方法是結構最簡單的行為型設計模式,在抽象類中定義了一個稱為模板方法的方法,在這個方法中定義其他基本方法的執行步驟,而基本方法的實現可以放在抽象類,也可以放在其子類


模式動機

現實生活中很多事情的完成過程都包含幾個基本步驟,例如請客吃飯,無論吃什麼,一般都包含點單、吃東西、買單幾個步驟,到底吃什麼則具體情況具體分析,在實際環境中由用戶動態決定。

既然這幾個步驟的次序是固定的,於是我們創建一個新的方法叫“請客”,在其中調用了點單、吃東西和買單,同時指定它們的執行次序,我們稱這個“請客”為模板方法,“點單”、“吃東西”、“買單”都是“請客”過程中的一個步驟,它們稱為基本方法。其中“吃東西”可以有多種吃法,如吃飯、吃麵條、吃燒烤,因此需要提供不同的“吃東西”方法的實現。

假設用代碼實現上述方法,我們可以把相同代碼放在父類,如“點單”和“買單”,而將不同方法實現放在不同的子類,如“吃東西”,這樣一來提高了代碼的復用性,還可以利用面向對象的多態性,這就是模板方法模式的模式動機。


模式定義

定義一個操作中演算法的骨架,而將一些步驟延遲到子類中,模板方法使得子類可以不改變一個演算法的結構即可重新定義該演算法的某些特定步驟

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.


模式分析

模板方法模式是基於繼承的代碼復用基本技術,先在抽象類的模板方法中指定執行步驟,將相同步驟對應的方法在抽象父類中實現,而不同的步驟只在抽象父類中進行聲明。由於面向對象的多態性,子類中定義的方法將覆蓋父類中定義的方法,因此程式運行時,具體子類的基本方法將覆蓋父類中定義的基本方法,實現特定的演算法。

不過,雖然說子類覆蓋了父類的方法實現業務邏輯,但實際上是由父類來控制整個過程,即子類不需要調用父類,而通過父類來調用子類。

由此得模式結構類圖如下:

抽象類(AbstractClass)中定義一系列基本操作(primitiveOperation),這些基本操作可以是具體的,也可以是抽象的,每一個基本操作對應演算法的一個步驟,在其子類中可以重定義並實現一個演算法的各個步驟。同時在抽象類中實現了一個模板方法(templateMethod),用於定義一個演算法的骨架,調用基本操作。

具體子類(ConcreteClass)用於實現在父類中定義的抽象基本操作以完成子類特定演算法的步驟,也可以覆蓋在父類中實現的具體基本操作。

基本方法是實現各個步驟的方法,是模板方法的組成部分,基本方法又可以分為三種:

  • 抽象方法

    一個抽象方法由抽象類聲明,由其具體子類實現

  • 具體方法

    一個具體方法由一個抽象類或具體類聲明並實現,其子類可以進行覆蓋

  • 鉤子方法

    一個鉤子方法由一個抽象類或具體類聲明並實現,而其子類可能會加以擴展。通常在父類中給出的實現是一個空實現,作為該方法的預設實現,當然也可以提高一個非空的預設實現。

    鉤子方法有兩類,一類是可以控制具體步驟的執行,比如說我們希望在不同條件下執行模板方法中的不同步驟,就可以定義一個返回類型為布爾值的鉤子方法,用於進行條件判斷,如果條件滿足則執行某一步驟,否則某一步驟不執行

    public void template() {
        open();
        display();
        if(isPrint()) {
            print();
        }
    }
    
    public boolean isPrint(){
        return true;
    }
    

    如果不希望方法執行,可以在其子類在覆蓋鉤子方法,修改返回值即可。

    還有一類鉤子方法是實現體為空的具體方法,子類根據需要覆蓋或繼承它們,與抽象方法相比,鉤子方法的好處在於如果沒有覆蓋父類中定義的抽象方法,編譯仍可以通過。


模式優缺點

模板方法模式的優點:

  • 可以在一個類中形式化地定義演算法,而由它的子類實現細節的處理
  • 模板方法模式是一種代碼復用的基本技術,在類庫設計中尤其重要,它提取類庫中的公共行為,將公共行為放在父類,通過子類來實現不同的行為
  • 通過一個父類調用其子類的操作,通過對子類的擴展增加新的行為,符合開閉原則

模板方法模式的缺點:

  • 每個不同的實現都需要定義一個子類,將會導致類的個數增加


您的分享是我們最大的動力!

更多相關文章
  • 項目根目錄下增加vue.config.js文件 // vue.config.js module.exports = { lintOnSave: false } ...
  • 隨著互聯網行業的火爆,近年來,想轉前端的學生和職場人越來越多,甚至出現了這樣一種現象:360行,行行轉前端。現在在網上隨便搜“轉行”、“前端”,都是醬紫的: 為什麼那麼多人都想做前端工程師?究其原因,就是前端有三好,薪資高,門檻低,前景也挺好。 Part.1 薪資高 讓我們先來看下某招聘網站統計的前 ...
  • 需求:當點擊input按鈕時候,彈出確認框,確認後提交到指定url,效果如下 分析:這裡面要,引入三個庫文件,如下是下載地址 layui樣式文件:https://layer.layui.com/ layer彈窗組件:https://www.layui.com/ jquery代碼庫:http://ww ...
  • 1、Web開發分類與區別 人們通常將Web分為前端和後端,前端相關的職位有前端設計師(UI/UE),前端開發工程師,後端相關的有後端開發工程師。 2、技術棧區別 看各大招聘網站上,公司對前端開發工程師的要求莫過於精通HTML,CSS,JS,有良好的交互設計能力等。再看公司對後端開發工程師的要求: 比 ...
  • 登高遠眺 天高地迥,覺宇宙之無窮 基礎技術 Lighthouse 測試內幕 文章分享了網易雲音樂前端性能監控平臺使用 Lighthouse 的實踐經驗,介紹了 Lighthouse 的測試流程、內部模塊實現以及性能指標計算等。文章循循善誘,使用清晰明瞭的架構圖和簡單易懂的代碼例子,剖析了 Light ...
  • 伺服器需要將發送的多媒體數據的類型告訴瀏覽器,而告訴瀏覽器的手段就是告知多媒體的MIME類型。 form表單中的enctype屬性,可以告訴伺服器,我們提供給它的內容的MIME類型。 enctype屬性有三種狀態值: 1). application/x-www-form-urlencoded 數據發 ...
  • 優秀的大前端人才應該具備熟練編寫任何一個互聯網系統的前端頁面、交互代碼的能力,作者從事IT6年,目前是一名全棧開發工程師,根據這些年在職場的經驗,結合目前互聯網環境下對於前端工程師的招聘要求分析,總結出企業要求主要分為硬核技能、輔助要求兩部分。 一、硬核技能 第一階段:HTML+CSS:HTML、C ...
  • 本人一直推崇寫流暢、自然、可自解釋的代碼,讓優雅成為一種習慣。 溫故而知新,聊一聊現代編程幾大常見的編程原則 普世原則 KISS (Keep It Simple Stupid) 保持系統結構簡單可信賴 YAGNI (you aren't gonna need it) 當前確實需要,再去做 Do Th ...
一周排行
  • 圖文講解,一門教學級邏輯式編程語言,NMiniKanren,的運行原理。 ...
  • 多Sheet導入教程 說明 本教程主要說明如何使用Magicodes.IE.Excel完成多個Sheet數據的Excel導入。 要點 多個相同格式的Sheet數據導入 多個不同格式的Sheet數據導入 主要步驟 1. 多個相同格式的Sheet數據導入 1.1 創建導入Sheet的Dto 主要代碼如下 ...
  • 在KeyPress事件中寫入 private void txtBoxKeyPress(object sender, KeyPressEventArgs e) { if ((e.KeyChar >= 'a' && e.KeyChar <= 'z') || (e.KeyChar >= 'A' && e. ...
  • 在 Xunit 中使用依賴註入 Intro 之前寫過一篇 xunit 的依賴註入相關的文章,但是實際使用起來不是那麼方便 今天介紹一個基於xunit和微軟依賴註入框架的“真正”的依賴註入使用方式 ——— Xunit.DependencyInjection, 來自大師的作品,讓你在測試代碼里使用依賴註 ...
  • 官網 http://www.hzhcontrols.com/ 前提 入行已經7,8年了,一直想做一套漂亮點的自定義控制項,於是就有了本系列文章。 GitHub:https://github.com/kwwwvagaa/NetWinformControl 碼雲:https://gitee.com/kww ...
  • 在項目的實際開發過程中,我們經常會遇到Tab頁面的開發 EciTab控制項有多種使用方式: 下麵介紹Frame容器方式: 下麵介紹的Tab頁面採用的策略是 Tab頁面管理幾個子頁面,頁面組織上用Iframe管理的模式 採用Iframe的原因主要有兩個 1.開發簡單,每一個頁面都是簡單的畫面 2.性能考 ...
  • 引用的DLL MySql.Data.MySqlClient System.Data City實體 public class City { public int ID { get; set; } public string Name { get; set; } public string Countr ...
  • 案例故事: 即時通訊(IM)軟體有很多,比如企業微信,釘釘,飛書,Skype, 微軟的Lync等, 這些軟體現在都很牛,還能監控誰誰在不在電腦旁工作,誰誰誰提前下班溜了。。。 一次偶然的機會,有個妹子請教我,她每天都想準時18點下班, 她問我如何做到: 假裝企業微信線上,併在2個小時後(20點)準時 ...
  • 一.官方文檔 https://pypi.org/project/muggle-ocr/ 二模塊安裝 pip install muggle-ocr # 因模塊過新,阿裡/清華等第三方源可能尚未更新鏡像,因此手動指定使用境外源,為了提高依賴的安裝速度,可預先自行安裝依賴:tensorflow/numpy ...
  • 前言 ​ 關於 Python 這個欄目,咕了幾個月了,今天講講如何發送驗證碼並驗證。 ​ 因為部分原因,寫這篇文章的時候心情是不太好的,播放首歌吧。 代碼 導入 導入yagmail,random和time庫 import yagmail,random,time #導入 yagmail , rando ...