設計模式之模版方法

模版方法介紹

模版方法(Template Method)模式是一種行為型設計模式它定義了一個操作(模板方法)的基本組合與控制流程,將一些步驟(抽象方法)推遲到子類中,使得子類可以在不改變算法結構的情況下,重新定義算法中的某些步驟。這種設計方式將特定步驟的具體實現與操作流程分離開來,實現了代碼的復用和擴展,從而提高代碼質量和可維護性。

1、模版方法模式的定義與原理

模版方法模式原始定義是:在操作中定義算法的框架,將一些步驟推遲到子類中。模版方法讓子類在不改變算法結構的情況下重新定義算法的某些步驟。這里的算法可以理解為廣義上的業務邏輯,并不是特指某一個實際的算法。

模版方法模式的主要原理包括:

  • 抽象父類:定義一個算法所包含的所有步驟,并提供一些通用的方法邏輯。
  • 具體子類:繼承自抽象父類,根據需要重寫父類提供的算法步驟中的某些步驟。

2、模版方法模式的角色

模版方法模式包含以下主要角色:

  • 抽象類(Abstract Class):負責給出一個算法的輪廓和骨架。它由一個模板方法和若干個基本方法構成。
  • 模板方法(Template Method):定義了算法的骨架,按某種順序調用其包含的基本方法。
  • 基本方法(Concrete Method):在抽象類中已經實現的方法,為算法的各個步驟提供默認實現。
  • 抽象方法(Abstract Method):在抽象類中聲明,由具體子類實現的方法,用于算法的某些特定步驟。
  • 鉤子方法(Hook Method):在抽象類中已經實現,包括用于判斷的邏輯方法和需要子類重寫的空方法兩種。鉤子方法提供了算法框架中的擴展點,允許子類在不改變算法結構的情況下,通過重寫這些方法來自定義算法的行為。

3、模版方法模式的優點與缺點

優點
  1. 提高代碼復用性:所有的子類可以復用父類中提供的模板方法代碼。
  2. 提高擴展性:框架通過模板模式提供功能擴展點,讓框架用戶可以在不修改框架源碼的情況下,基于擴展點定制化框架的功能。
  3. 明確算法結構:通過模板方法,可以清晰地定義算法的框架和步驟,使得算法的結構更加明確和易于理解。
缺點
  1. 類數量增加:由于每個算法都需要一個抽象類和具體子類來實現,因此在操作流程比較多時可能導致類的數量急劇增加,從而導致代碼的復雜性提高。
  2. 關聯性高:模板方法與子類實現的抽象方法緊密相關,如果該模板方法需要修改,可能會涉及到多個子類的修改。

4、模版方法模式的應用場景

模版方法模式適用于以下場景:

  • 當多個類有共同的算法結構,但具體的實現步驟可能有所不同時。
  • 當需要在不改變算法結構的情況下,對算法的某些步驟進行定制時。
  • 當需要提高代碼的復用性和擴展性時。

例如,在軟件開發中,經常需要處理各種業務邏輯流程,這些流程通常具有相似的結構但具體的實現步驟可能因業務需求的不同而有所差異。此時,可以使用模版方法模式來定義這些流程的框架和步驟,然后通過不同的子類來實現具體的業務邏輯。這樣可以減少代碼的重復,提高代碼的可維護性和可擴展性。

二、模版方法實現例子

以下是一個用Java編寫的模版方法模式的例子。在這個例子中,我們將創建一個抽象類Game,它定義了一個游戲的基本流程(即模版方法),包括初始化游戲、玩游戲和結束游戲等步驟。然后,我們創建兩個具體的游戲類VideoGameBoardGame,它們分別實現了這些步驟中的特定行為。

// 抽象游戲類  
abstract class Game {  // 模版方法,定義了游戲的流程  final void play() {  initializeGame();  while (!gameOver()) {  playStep();  }  endGame();  }  // 抽象方法,需要子類實現  abstract void initializeGame();  // 抽象方法,需要子類實現  abstract void playStep();  // 抽象方法,判斷游戲是否結束,可以提供一個默認實現,也可以留空讓子類實現  abstract boolean gameOver();  // 鉤子方法,可以在需要時由子類重寫  void endGame() {  System.out.println("Game Over!");  }  
}  // 視頻游戲類  
class VideoGame extends Game {  @Override  void initializeGame() {  System.out.println("Initializing Video Game...");  }  @Override  void playStep() {  System.out.println("Playing Video Game Step...");  // 這里可以添加更多的游戲步驟邏輯  }  @Override  boolean gameOver() {  // 這里簡化為總是返回true以結束游戲  // 在實際游戲中,這里應該包含判斷游戲是否結束的邏輯  return true;  }  // 可以選擇重寫鉤子方法以提供自定義的結束游戲邏輯  // 但在這個例子中,我們使用父類的默認實現  
}  // 桌游類  
class BoardGame extends Game {  @Override  void initializeGame() {  System.out.println("Setting up Board Game...");  }  @Override  void playStep() {  System.out.println("Playing Board Game Turn...");  // 這里可以添加更多的游戲回合邏輯  }  @Override  boolean gameOver() {  // 這里簡化為總是返回true以結束游戲  // 在實際游戲中,這里應該包含判斷游戲是否結束的邏輯  return true;  }  // 同樣,可以選擇重寫鉤子方法  
}  // 客戶端類  
public class TemplateMethodPatternDemo {  public static void main(String[] args) {  Game videoGame = new VideoGame();  System.out.println("Playing Video Game:");  videoGame.play();  Game boardGame = new BoardGame();  System.out.println("\nPlaying Board Game:");  boardGame.play();  }  
}

在這個例子中,Game類定義了一個游戲的模版方法play(),它按照初始化游戲、玩游戲步驟(循環直到游戲結束)、結束游戲的順序來執行。initializeGame()playStep()gameOver()是抽象方法,需要由子類來實現具體的游戲邏輯。endGame()是一個鉤子方法,它提供了一個默認的實現,但子類可以根據需要重寫它。

VideoGameBoardGame類分別實現了Game類的抽象方法,以提供各自的游戲邏輯。在main方法中,我們創建了VideoGameBoardGame的實例,并調用了它們的play()方法來玩游戲。由于play()方法是final的,因此它不能被子類重寫,這保證了游戲流程的一致性。然而,通過重寫抽象方法和鉤子方法,子類可以靈活地實現自己的游戲邏輯。

如果覺得不錯,記得點贊收藏,你們的反饋是我不斷創作的動力。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/41298.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/41298.shtml
英文地址,請注明出處:http://en.pswp.cn/web/41298.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

旅游 | 西岳華山

得到了再失去, 總比從來沒有得到更傷人。 ——胡賽尼《追風箏的人》 目錄 旅游 | 西岳華山00 | 旅游導圖01 | 旅游路線02 | 必帶行李03 | 旅游費用3.1 門票3.2 索道價格3.2.1 北峰索道(單程)3.2.1 西峰索道(單程) 3.3 …

掌握 IPython 歷史的藝術:%dhist 命令的深度指南

掌握 IPython 歷史的藝術:%dhist 命令的深度指南 在 IPython 的交互式探索中,歷史命令是我們最寶貴的資源之一。%dhist 命令是 IPython 提供的一個強大工具,它允許用戶瀏覽、搜索和重新執行歷史中的命令。本文將深入探討 %dhist 命令的使用方…

【UE5.1】Chaos物理系統基礎——03 炸開幾何體集

目錄 步驟 一、通過徑向向量將幾何體集炸開 二、優化炸開效果——讓破裂的碎塊自然下落 三、優化炸開效果——讓碎塊旋轉起來 四、優化炸開效果——讓碎塊旋轉的越來越慢 步驟 一、通過徑向向量將幾何體集炸開 1. 打開上一篇中(【UE5.1】Chaos物理系統基礎—…

Spring IOC基于XML和注解管理Bean

IoC 是 Inversion of Control 的簡寫,譯為“ 控制反轉 ”,它不是一門技術,而是一種設計思想,是一個重要的面向對象編程法則,能夠指導我們如何設計出 松耦合、更優良的程序。 Spring 通過 IoC 容器來管理所有 Java 對象…

如何從 Windows 11/10/8.1/8/7 恢復已刪除的視頻

意外刪除了視頻或格式化了 SD 卡/硬盤?沒有備份已刪除的視頻?別擔心,我們有解決方案來恢復 Windows 11、10 中已刪除的視頻并處理這種糟糕的情況。 但在了解如何恢復已刪除的視頻和視頻恢復應用程序之前,請知道 Windows 會為您提…

ARMv8寄存器詳解

文章目錄 一、ARMv8寄存器介紹二、通用寄存器三、 PSTAE寄存器四、特殊寄存器五、系統寄存器 一、ARMv8寄存器介紹 本文我來給大家介紹一下ARMv8的寄存器部分,ARMv8中有34個寄存器,包括31個通用寄存器、一個棧指針寄存器SP(X31),一個程序計數器寄存器PC…

Apache Drill 2萬字面試題及參考答案

目錄 什么是Apache Drill? Apache Drill的主要特點是什么? Apache Drill如何實現對復雜數據的查詢? 描述Apache Drill的數據存儲模型。 為什么Apache Drill被稱為自服務的SQL查詢引擎? Apache Drill支持哪些類型的數據源? 解釋Apache Drill中的“schema discovery”…

Transformer前置知識:Seq2Seq模型

Seq2Seq model Seq2Seq(Sequence to Sequence)模型是一類用于將一個序列轉換為另一個序列的深度學習模型,廣泛應用于自然語言處理(NLP)任務,如機器翻譯、文本摘要、對話生成等。Seq2Seq模型由編碼器&#…

《框架封裝 · 統一異常處理和返回值包裝》

📢 大家好,我是 【戰神劉玉棟】,有10多年的研發經驗,致力于前后端技術棧的知識沉淀和傳播。 💗 🌻 CSDN入駐不久,希望大家多多支持,后續會繼續提升文章質量,絕不濫竽充數…

貪心算法-以高校科研管理系統為例

1.貪心算法介紹 1.算法思路 貪心算法的基本思路是從問題的某一個初始解出發一步一步地進行,根據某個優化測度,每一 步都要確保能獲得局部最優解。每一步只考慮一 個數據,其選取應該滿足局部優化的條件。若下 一個數據和部分最優解連在一起…

JavaEE初階-網絡原理1

文章目錄 前言一、UDP報頭二、UDP校驗和2.1 CRC2.2 md5 前言 學習一個網絡協議,最主要就是學習的報文格式,對于UDP來說,應用層數據到達UDP之后,會給應用層數據報前面加上UDP報頭。 UDP數據報UDP包頭載荷 一、UDP報頭 如上圖UDP的…

Kubernetes(K8s) kubectl 常用命令

文章目錄 一、常用命令1.1 kubectl describe 命令 二、kubectl 命令中的簡寫三、Helm3.1 常用命令:3.2 遇到的問題3.2.1 cannot re-use a name that is still in use 四、Containerd 一、常用命令 檢查 k8s 各節點狀態,確保k8s集群各節點狀態正常&#x…

概率基礎——矩陣正態分布matrix normal distribution

矩陣正態分布-matrix normal distribution 定義性質應用 最近碰到了這個概念,記錄一下 矩陣正態分布是一種推廣的正態分布,它應用于矩陣形式的數據。矩陣正態分布在多維數據分析、貝葉斯統計和機器學習中有廣泛的應用。其定義和性質如下: 定…

Emacs之解決:java-mode占用C-c C-c問題(一百四十六)

簡介: CSDN博客專家,專注Android/Linux系統,分享多mic語音方案、音視頻、編解碼等技術,與大家一起成長! 優質專欄:Audio工程師進階系列【原創干貨持續更新中……】🚀 優質專欄:多媒…

【django項目使用easycython編譯】Cannot convert Unicode string to ‘str‘ implicitly.

django項目編譯遇到的問題 報錯條件 需要編譯的python源碼里面的函數寫了type hint,尤其是return的type hint, 當type hint是str時,但是變量確實f-string格式化后得到的,編譯時會報錯 報錯原因 easycython會檢查變量類型&…

軟件開發中的原型開發與需求文檔開發:哪個更優?

1. 引言 在軟件開發過程中,選擇合適的開發方法對于項目的成功至關重要。基于原型開發和基于需求文檔開發是兩種常見的開發方法,各自有其優點和缺點。在項目復雜性、客戶需求和資源限制等因素的影響下,開發團隊需要慎重選擇適合的開發方法。 …

C++語言相關的常見面試題目(二)

1.vector底層實現原理 以下是 std::vector 的一般底層實現原理: 內存分配:當創建一個 std::vector 對象時,會分配一塊初始大小的連續內存空間來存儲元素。這個大小通常會隨著 push_back() 操作而動態增加。 容量和大小:std::vec…

element-plus 的form表單組件之el-radio(單選按鈕組件)

單選按鈕組件適用于同一組類型的選項只能互斥選擇的場景,就是支持單選。單選組件包含以下3個組件 組件名作用el-radio-group單選組組件,子元素可以是el-radio或el-radio-button,v-mode綁定單選組的響應式屬性el-radio單選組件,la…

階段三:項目開發---搭建項目前后端系統基礎架構:任務9:導入空管基礎數據

任務描述 本階段任務是導入項目的基礎數據,包括空管基礎數據和離線的實時飛行數據(已經脫敏)。 任務指導 本階段任務需要導入兩種數據: 1、在MySQL中導入空管基礎數據 kongguan.sql空管基礎數據表說明: 1告警信息…

OpenCV直方圖計算函數calcHist的使用

操作系統:ubuntu22.04OpenCV版本:OpenCV4.9IDE:Visual Studio Code編程語言:C11 功能描述 圖像的直方圖是一種統計表示方法,用于展示圖像中不同像素強度(通常是灰度值或色彩強度)出現的頻率分布。具體來說…