模板方法模式 詳解 設計模式

模板方法模式

模板方法模式是一種行為型設計模式,它定義了一個算法的骨架,將一些步驟延遲到子類中實現。這種模式允許子類在不改變算法結構的情況下重新定義算法的某些步驟。

結構

  • 抽象類(Abstract Class):負責給出一個算法的輪廓和骨架。它由一個模板方法和若干個基本方法構成。其中包含了一些基本操作的步驟,有些步驟由具體子類實現。

    • 模板方法:定義了算法的骨架,按某種順序調用其包含的基本方法。

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

      • 抽象方法(Abstract Method) :一個抽象方法由抽象類聲明、由其具體子類實現。

      • 具體方法(Concrete Method) :一個具體方法由一個抽象類或具體類聲明并實現,其子類可以進行覆蓋也可以直接繼承。

      • 鉤子方法(Hook Method) :在抽象類中已經實現,包括用于判斷的邏輯方法需要子類重寫的空方法兩種。

        一般鉤子方法是用于判斷的邏輯方法,這類方法名一般為isXxx,返回值類型為boolean類型。

  • 具體子類(Concrete Class):實現抽象類中所定義的抽象方法和鉤子方法,它們是一個頂級邏輯的組成步驟。

案例:

你制作一個飲料,步驟是確定的,像燒水; 釀造;倒入杯中,添加調味品。燒水和倒杯是固定的基本操作,釀造和添加調味料這個則是通過具體的情況來定的。

代碼實現:

// 抽象類
abstract  class Beverage {// 模板方法,定義了算法的骨架public final void prepareBeverage() {boilWater();brew();pourInCup();addCondiments();}// 抽象方法,由子類實現abstract void brew();abstract void addCondiments();// 公共方法,由父類實現void boilWater() {System.out.println("Boiling water");}void pourInCup() {System.out.println("Pouring into cup");}
}// 具體類1
class Coffee extends Beverage {@Overridevoid brew() {System.out.println("Dripping coffee through filter");}@Overridevoid addCondiments() {System.out.println("Adding sugar and milk");}
}// 具體類2
class Tea extends Beverage {@Overridevoid brew() {System.out.println("Steeping the tea");}@Overridevoid addCondiments() {System.out.println("Adding lemon");}
}// 使用示例
public class Main {public static void main(String[] args) {Beverage coffee = new Coffee();coffee.prepareBeverage();System.out.println();Beverage tea = new Tea();tea.prepareBeverage();}
}

注意:為防止惡意操作,一般模板方法都加上 final 關鍵詞。

使用場景:

  • 當有一系列算法步驟,其中有一部分是固定的,但是另一部分需要在子類中具體實現時,可以考慮使用模板方法模式。
  • 當需要在不同的子類中重用相同的算法框架時,可以使用模板方法模式。

以下是模板方法模式在開發后臺管理系統中的使用場景示例:

  1. 權限管理: 在后臺管理系統中,通常需要對不同用戶或用戶組的權限進行管理。模板方法模式可以定義一個權限管理的骨架,包括權限驗證、權限分配等操作,而具體的權限驗證和分配操作可以交由子類實現。
  2. 數據的增刪改查: 后臺管理系統通常需要對數據進行增加、刪除、修改、查詢等操作。可以使用模板方法模式定義一個數據操作的骨架,包括數據的驗證、數據的持久化等步驟,而具體的數據操作可以由子類實現。
  3. 數據的導入導出: 后臺管理系統可能需要支持數據的導入導出功能,例如從 Excel 文件中導入數據到數據庫,或者將數據庫中的數據導出為 Excel 文件。可以使用模板方法模式定義一個數據導入導出的骨架,包括數據格式的驗證、數據的轉換等步驟,而具體的導入導出操作可以由子類實現。
  4. 日志記錄: 后臺管理系統通常需要記錄用戶的操作日志,例如登錄日志、操作日志等。可以使用模板方法模式定義一個日志記錄的骨架,包括日志的格式化、日志的存儲等步驟,而具體的日志記錄操作可以由子類實現。

優缺點:

優點:

  • 提高代碼復用性

    將相同部分的代碼放在抽象的父類中,而將不同的代碼放入不同的子類中。

  • 實現了反向控制

    通過一個父類調用其子類的操作,通過對子類的具體實現擴展不同的行為,實現了反向控制 ,并符合“開閉原則”。

缺點:

  • 對每個不同的實現都需要定義一個子類,這會導致類的個數增加,系統更加龐大,設計也更加抽象。
  • 父類中的抽象方法由子類實現,子類執行的結果會影響父類的結果,這導致一種反向的控制結構,它提高了代碼閱讀的難度。

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

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

相關文章

JavaWeb老杜視頻筆記總結,Servlet-JSP

關于直播 什么時間直播? 晚上8:00到10:00 每周直播幾天? 3天(周一、周三、周五) 本周比較特殊:周四周五周六三天直播,從下周開始就是一三五直播。 直播什么內容? 從JavaWEB開始。&#xff08…

《深入淺出紅黑樹:一起動手實現自平衡的二叉搜索樹》

一、分析 1. 紅黑樹的性質 紅黑樹是一種自平衡的二叉搜索樹,它具有以下五個性質: (1)節點是紅色或黑色。 (2)根節點是黑色。 (3)所有葉子節點(NIL節點)是…

探索數據宇宙:深入解析大數據分析與管理技術

?? 歡迎大家來訪Srlua的博文(づ ̄3 ̄)づ╭?~?? 🌟🌟 歡迎各位親愛的讀者,感謝你們抽出寶貴的時間來閱讀我的文章。 我是Srlua,在這里我會分享我的知識和經驗。&#x…

第六課:NIO簡介

一、傳統BIO的缺點 BIO屬于同步阻塞行IO,在服務器的實現模型為,每一個連接都要對應一個線程。當客戶端有連接請求的時候,服務器端需要啟動一個新的線程與之對應處理,這個模型有很多缺陷。當客戶端不做出進一步IO請求的時候,服務器…

《Spring Security 簡易速速上手小冊》第4章 授權與角色管理(2024 最新版)

文章目錄 4.1 理解授權4.1.1 基礎知識詳解授權的核心授權策略方法級安全動態權限檢查 4.1.2 主要案例:基于角色的頁面訪問控制案例 Demo 4.1.3 拓展案例 1:自定義投票策略案例 Demo測試自定義投票策略 4.1.4 拓展案例 2:使用方法級安全進行細…

【flutter】加載指示器(loading indicator)阻止用戶在某個操作執行期間操作頁面

在Flutter中,通過顯示一個加載指示器(loading indicator)來阻止用戶在某個操作執行期間操作頁面。以下是一個簡單的示例代碼,演示了按鈕被點擊后執行某操作,在操作完成前顯示加載指示器,阻止用戶操作頁面&a…

c語言數據結構(5)——棧

歡迎來到博主的專欄——C語言數據結構 博主id:代碼小豪 文章目錄 棧棧的順序存儲結構棧的插入空棧的初始化棧的刪除判斷空棧讀取棧頂元素數據 實現順序棧的所有代碼棧的鏈式存儲結構鏈式棧的初始化鏈式棧的入棧操作鏈式棧的出棧操作 實現鏈式棧的所有代碼 棧 棧是…

學習網絡編程No.11【傳輸層協議之UDP】

引言: 北京時間:2023/11/20/9:17,昨天成功更文,上周實現了更文兩篇,所以這周再接再厲。當然做題任在繼續,而目前做題給我的感覺以套路和技巧偏多,還是那句話很多東西不經歷你就是不懂&#xff…

測試人員如何向開發人員準確清晰地描述問題?

測試人員向開發人員準確清晰地描述問題可以采取以下方法: 提供詳細的背景和上下文信息:描述問題發生的環境、前提條件和操作步驟,讓開發人員能夠了解問題出現的場景。明確問題的癥狀和表現:清楚地說明問題的具體表現,…

【Python】2. 基礎語法

常量和表達式 我們可以把 Python 當成一個計算器, 來進行一些算術運算. 注意: print 是一個 Python 內置的 函數, 這個稍后詳細介紹. 可以使用 - * / ( ) 等運算符進行算術運算. 先算乘除, 后算加減. 運算符和數字之間, 可以沒有空格, 也可以有多個空格. 但是一般習慣上寫一…

LDR6328芯片:智能家居時代的小家電充電革新者

在當今的智能家居時代,小家電的供電方式正變得越來越智能化和高效化。 利用PD(Power Delivery)芯片進行誘騙取電,為后端小家電提供穩定電壓的技術,正逐漸成為行業的新寵。在這一領域,LDR6328芯片以其出色的…

Qt下使用modbus-c庫實現PLC線圈/保持寄存器的讀寫

系列文章目錄 提示:這里是該系列文章的所有文章的目錄 第一章:Qt下使用ModbusTcp通信協議進行PLC線圈/保持寄存器的讀寫(32位有符號數) 第二章:Qt下使用modbus-c庫實現PLC線圈/保持寄存器的讀寫 文章目錄 系列文章目錄…

前端Vue3項目如何打包成Docker鏡像運行

將前端Vue3項目打包成Docker鏡像并運行包括幾個主要步驟:項目打包、編寫Dockerfile、構建鏡像和運行容器。下面是一個基本的流程: 1. 項目打包 首先,確保你的Vue3項目可以正常運行和打包。在項目根目錄下執行以下命令來打包你的Vue3項目&am…

nest.js使用nest-winston日志一

nest-winston文檔 nest-winston - npm 參考:nestjs中winston日志模塊使用 - 浮的blog - SegmentFault 思否 安裝 cnpm install --save nest-winston winstoncnpm install winston-daily-rotate-file 在main.ts中 import { NestFactory } from nestjs/core; im…

【5G 接口協議】GTP-U協議介紹

博主未授權任何人或組織機構轉載博主任何原創文章,感謝各位對原創的支持! 博主鏈接 本人就職于國際知名終端廠商,負責modem芯片研發。 在5G早期負責終端數據業務層、核心網相關的開發工作,目前牽頭6G算力網絡技術標準研究。 博客…

mysql學習

查看glibc版本 ldd --version --mysql啟動失敗,嘗試啟動 1 查看錯誤日志,端口被占用,參數名寫錯,有不支持的參數 2 通過mysqld啟動 mysqld --default-filemy.cnf & 3 mysqld --no-defaults --basedir/user/local/mysql --datadir/data/mysql/3306/data/ --usermysql 4 str…

深入理解 Nginx 的負載均衡與反向代理

深入理解 Nginx 的負載均衡與反向代理 Nginx 是一個高性能的 HTTP 和反向代理服務器,也是一個 IMAP/POP3/SMTP 代理服務器。由于其出色的性能和靈活性,Nginx 已成為現代 web 架構中的重要組成部分,尤其是在處理高并發連接和大規模流量時。在…

找到數組的中間位置-1991-[簡單]

力扣 關鍵點 從題目中總結出公式 sum * 2 nums[i] total從左往右開始嘗試,尋找 i 位置滿足上面的公式,為什么從左開始,因為題目要求找到最左邊的一個用前綴和的概念來解,從左往右嘗試i位置的左邊所有數之和,右邊所有…

基礎小白快速入門Python------>模塊的作用和意義

模塊, 這個詞聽起來是如此的高大威猛,以至于萌新小白見了瑟瑟發抖,本草履蟲見了都直搖頭,好像聽上去很難的樣子,但是但是,年輕人,請聽本少年細細講述,他只是看起來很難,實…

GO-接口

1. 接口 在Go語言中接口(interface)是一種類型,一種抽象的類型。 interface是一組method的集合,接口做的事情就像是定義一個協議(規則),只要一臺機器有洗衣服和甩干的功能,我就稱它…