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

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

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



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


模式動機

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

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

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


模式定義

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

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;
    }
    

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

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


模式優缺點

模板方法模式的優點:

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

模板方法模式的缺點:

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


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

-Advertisement-
Play Games
更多相關文章
  • 項目根目錄下增加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 ...
一周排行
    -Advertisement-
    Play Games
  • 1. 說明 /* Performs operations on System.String instances that contain file or directory path information. These operations are performed in a cross-pla ...
  • 視頻地址:【WebApi+Vue3從0到1搭建《許可權管理系統》系列視頻:搭建JWT系統鑒權-嗶哩嗶哩】 https://b23.tv/R6cOcDO qq群:801913255 一、在appsettings.json中設置鑒權屬性 /*jwt鑒權*/ "JwtSetting": { "Issuer" ...
  • 引言 集成測試可在包含應用支持基礎結構(如資料庫、文件系統和網路)的級別上確保應用組件功能正常。 ASP.NET Core 通過將單元測試框架與測試 Web 主機和記憶體中測試伺服器結合使用來支持集成測試。 簡介 集成測試與單元測試相比,能夠在更廣泛的級別上評估應用的組件,確認多個組件一起工作以生成預 ...
  • 在.NET Emit編程中,我們探討了運算操作指令的重要性和應用。這些指令包括各種數學運算、位操作和比較操作,能夠在動態生成的代碼中實現對數據的處理和操作。通過這些指令,開發人員可以靈活地進行算術運算、邏輯運算和比較操作,從而實現各種複雜的演算法和邏輯......本篇之後,將進入第七部分:實戰項目 ...
  • 前言 多表頭表格是一個常見的業務需求,然而WPF中卻沒有預設實現這個功能,得益於WPF強大的控制項模板設計,我們可以通過修改控制項模板的方式自己實現它。 一、需求分析 下圖為一個典型的統計表格,統計1-12月的數據。 此時我們有一個需求,需要將月份按季度劃分,以便能夠直觀地看到季度統計數據,以下為該需求 ...
  • 如何將 ASP.NET Core MVC 項目的視圖分離到另一個項目 在當下這個年代 SPA 已是主流,人們早已忘記了 MVC 以及 Razor 的故事。但是在某些場景下 SSR 還是有意想不到效果。比如某些靜態頁面,比如追求首屏載入速度的時候。最近在項目中回歸傳統效果還是不錯。 有的時候我們希望將 ...
  • System.AggregateException: 發生一個或多個錯誤。 > Microsoft.WebTools.Shared.Exceptions.WebToolsException: 生成失敗。檢查輸出視窗瞭解更多詳細信息。 內部異常堆棧跟蹤的結尾 > (內部異常 #0) Microsoft ...
  • 引言 在上一章節我們實戰了在Asp.Net Core中的項目實戰,這一章節講解一下如何測試Asp.Net Core的中間件。 TestServer 還記得我們在集成測試中提供的TestServer嗎? TestServer 是由 Microsoft.AspNetCore.TestHost 包提供的。 ...
  • 在發現結果為真的WHEN子句時,CASE表達式的真假值判斷會終止,剩餘的WHEN子句會被忽略: CASE WHEN col_1 IN ('a', 'b') THEN '第一' WHEN col_1 IN ('a') THEN '第二' ELSE '其他' END 註意: 統一各分支返回的數據類型. ...
  • 在C#編程世界中,語法的精妙之處往往體現在那些看似微小卻極具影響力的符號與結構之中。其中,“_ =” 這一組合突然出現還真不知道什麼意思。本文將深入剖析“_ =” 的含義、工作原理及其在實際編程中的廣泛應用,揭示其作為C#語法奇兵的重要角色。 一、下劃線 _:神秘的棄元符號 下劃線 _ 在C#中並非 ...