23種設計模式-行為型模式-模板方法

文章目錄

  • 簡介
  • 場景
  • 解決
    • 代碼
    • 關鍵優化點
  • 總結

簡介

模板方法是一種行為設計模式,它在超類中定義了一個算法的框架,允許子類在不修改結構的情況下重寫算法的特定步驟。

場景

假如你正在開發一款分析文檔的數據挖掘程序。用戶需要向程序輸入各種格式(PDF、DOC 或 CSV)的文檔,程序會試圖從這些文件中提取有意義的數據,再以統一的格式返回給用戶。
程序的首個版本只支持 DOC 文件。下個版本,程序需要支持 CSV 文件。一個月后,程序又需要從 PDF 文件中抽取數據。
數據挖掘類中包含許多重復代碼。
一段時間后,你發現這三個類中包含許多相似代碼。盡管讀取不同格式數據的代碼完全不同,但數據處理和分析的代碼卻幾乎完全一樣。怎么在保持算法結構完整的情況下去除重復代碼?這是第一個問題。
還有另一個與使用這些類的客戶端代碼相關的問題:客戶端代碼中包含許多條件語句,因為它要根據不同的文檔類型選擇合適的處理過程。 如果所有處理數據的類都有相同的接口或基類,那你就可以去除客戶端代碼里的條件語句,轉而使用多態機制來調用處理對象的方法。

解決

模板方法模式建議把算法分解為一系列步驟,然后將這些步驟改寫為方法,最后在“模板方法”中依次調用這些方法。步驟可以是抽象的,也可以有一些默認的實現。為了能夠使用算法,客戶端需要自己提供子類,并且實現所有的抽象步驟。可能還需重寫一些步驟(但這一步中不包括模板方法自身)。
讓我們想想怎么在數據挖掘程序里運用這樣的方案。我們可為三個解析算法創建一個基類,這個類定義了一個模板方法-mine方法,這個方法會在內部調用不同的文檔處理步驟。
模板方法將算法分解為步驟,并允許子類重寫這些步驟,而非重寫實際的模板方法。

首先,我們將所有步驟聲明為抽象類型,強制要求子類自行實現這些方法。在我們的例子里,子類已經實現了必須的方法,因此我們只需調整這些方法的名稱,讓他跟超類的方法匹配就行了。
現在,讓我們看看怎么去除子類里的重復代碼。對于不同的文件格式,打開和關閉文件以及讀取解析數據的代碼都不同,所以不需要修改這些方法。但分析原始數據和生成報告等其他步驟的實現方式非常相似,所以可以把他們提取到基類里,讓子類共享這些代碼。
所以我們有兩種類型的步驟:

  1. 抽象步驟必須由各個子類來實現
  2. 可選步驟已經有一些默認實現,但你仍然可以在需要時進行重寫
    還有另一種名為鉤子 hook 的步驟。鉤子是內容為空的可選的步驟。即使子類不重寫鉤子,模板方法也能工作。鉤子通常放置在算法重要步驟的前后,為子類提供額外的算法擴展點。

代碼

// 抽象類定義模板方法
abstract class DataMiner {// 模板方法(不可被覆蓋)public final void processDocument() {  openDocument();extractRawData();parseData();           // 抽象步驟analyzeData();         // 通用實現generateReport();      // Hook方法}// 文檔打開基礎實現protected void openDocument() {  System.out.println("打開文檔...");}// 數據抽取基礎實現protected void extractRawData() {  System.out.println("抽取原始數據...");}// 解析算法必須子類實現protected abstract void parseData();  // 通用分析實現protected void analyzeData() {  System.out.println("執行數據聚類分析...");}/* 鉤子方法(可選覆蓋) */protected void generateReport() {  System.out.println("生成基礎統計報表");}
}// 具體子類實現
class PDFDataMiner extends DataMiner {@Overrideprotected void parseData() {  // 實現特定解析邏輯System.out.println("解析PDF版式結構");System.out.println("提取PDF文本流");}
}class CSVDataMiner extends DataMiner {@Overrideprotected void parseData() {  System.out.println("識別CSV分隔符");System.out.println("映射CSV字段");}@Overrideprotected void generateReport() {  // 自定義Hook實現super.generateReport();System.out.println("追加CSV格式驗證結果");}
}// 客戶端調用示例
class Client {public static void main(String[] args) {System.out.println("處理PDF文檔:");DataMiner pdfProcessor = new PDFDataMiner();pdfProcessor.processDocument();  // 執行完整流程System.out.println("\n處理CSV文檔:");DataMiner csvProcessor = new CSVDataMiner();csvProcessor.processDocument();}
}

關鍵優化點

  1. 固定流程:不可重寫的processDocument()確保流程一致
  2. 職責分離:各子類僅需實現格式相關解析邏輯
  3. 擴展能力:通過鉤子方法實現可選擴展(如CSV格式驗證)

總結

在這里插入圖片描述

  1. 抽象類(Abstract-Class)會聲明算法步驟的方法(step1,step2…),以及依次調用它們的模板方法(templateMethod)。算法步驟可以被聲明為抽象類型,也可以提供一些默認實現。
  2. 具體類(Con-crete-Class)可以重寫所有步驟,但不能重寫模板方法自身。

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

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

相關文章

解決Long類型前端精度丟失和正常傳回后端問題

在 Java 后端開發中,可能會遇到前后端交互過程中 Long 類型精度丟失的問題。尤其是在 JavaScript 中,由于其 Number 類型是雙精度浮點數,超過 16 位的 Long 類型值就會發生精度丟失。 問題背景 假設有如下實體類: public class…

PowerPhotos:拯救你的Mac照片庫,告別蘋果原生應用的局限

如果你用Mac管理照片,大概率被蘋果原生「照片」應用折磨過——無法真正并行操作多個圖庫。每次切換圖庫都要關閉重啟,想合并照片得手動導出導入,重復文件更是無處可逃…… 直到我發現了 PowerPhotos,這款專為Mac設計的照片庫管理…

android 14.0 工廠模式 測試音頻的一些問題(高通)

1之前用tinycap,現在得用agmcap 執行----agmcap /data/test.wav -D 100 -d 101 -i CODEC_DMA-LPAIF_RXTX-TX-3 -T 3 報錯1 agmcap data/test.wav -D 100 -d 101 -i CODEC_DMA-LPAIF_RXTX-TX-3 -T 3 Failed to open xml file name /vendor/etc/backend_co…

以庫存系統為核心的ERP底層架構設計

在企業資源計劃(ERP)系統中,庫存系統常被視為基礎模塊。但在現代企業的數字化進程中,庫存系統不僅僅是一個模塊,它已經逐步演化為驅動整個ERP生態的核心引擎。本文從架構設計的角度,探討為何庫存系統應被置…

辛格迪客戶案例 | 北京舒曼德醫藥實施電子合約系統(eSign)

01 北京舒曼德醫藥科技開發有限公司:醫藥科技的數字化先鋒 北京舒曼德醫藥科技開發有限公司(以下簡稱“舒曼德醫藥”)作為國內醫藥科技領域的領軍企業,致力于創新藥物的研發、臨床試驗和市場推廣。公司以“科技興藥、質量為先、服…

【UE5】RTS游戲的框選功能+行軍線效果實現

目錄 效果 步驟 一、項目準備 二、框選NPC并移動到指定地點 三、框選效果 效果 步驟 一、項目準備 1. 新建一個俯視角游戲工程 2. 新建一個pawn、玩家控制器和游戲模式,這里分別命名為“MyPawn”、“MyController”和“MyGameMode” 3. 打開“MyGameMode”,設置玩家…

vim定位有問題的腳本/插件的一般方法

在使用vim的過程中可能會遇到一些報錯或其他不符合預期的情況,本文介紹一些我自己常用的定位有問題腳本/插件的方法(以下方法同樣適用于neovim) 執行了某些命令的情況 這種情況最簡單,使用:h 命令,如果插件有文檔的話…

智能驅動教育變革:人工智能在高中教育中的實踐路徑與創新策略

一、引言 隨著信息技術的飛速發展,人工智能(Artificial Intelligence, AI)已成為推動社會進步的重要力量。在教育領域,人工智能的應用正逐漸改變著傳統的教學模式和方法,為教育現代化注入了新的活力。高中教育作為教育…

VLAN(虛擬局域網)

一、vlan概述 VLAN(virtual local area network)是一種通過邏輯方式劃分網絡的技術,允許將一個物理網絡劃分為多個獨立的虛擬網絡。每一個vlan是一個廣播域,不同vlan之間的通信需要通過路由器或三層交換機 [!注意] vlan是交換機獨有的技術,P…

spring-cloud-starter-alibaba-seata使用說明

Spring Cloud Alibaba Seata 使用說明 spring-cloud-starter-alibaba-seata 是 Spring Cloud Alibaba 生態中用于集成分布式事務框架 Seata 的核心組件,支持 AT(自動補償)、TCC(手動補償) 等模式。 一、依賴配置 添加…

每日一題(小白)暴力娛樂篇23

由題意得知給我們一串數字,我們每次交換兩位,最少交換多少次成功得到有順序的數組。我們以平常的思維去思考,加入給你一串數字獲得最少的交換次數,意味著你的交換后續基本不會變,比如說2 1 3 5 4 中1與2交換后不變&…

Python基礎——Pandas庫

對象的創建 導入 Pandas 時,通常給其一個別名“pd”,即 import pandas as pd。作為標簽庫,Pandas 對象在 NumPy 數組基礎上給予其行列標簽。可以說,列表之于字典,就如 NumPy 之于 Pandas。Pandas 中,所有數…

Spring入門概念 以及入門案例

Spring入門案例 Springspring是什么spring的狹義與廣義spring的兩個核心模塊IoCAOP Spring framework特點spring入門案例不用new方法,如何使用返回創建的對象 容器:IoC控制反轉依賴注入 Spring spring是什么 spring是一款主流的Java EE輕量級開源框架 …

The packaging for this project did not assign a file to the build artifact

問題: maven install報錯:The packaging for this project did not assign a file to the build artifact 解決方案: 方案1: 使用mvn clean install 就可以解決問題, 方案2: 找到lifecycle點clean再點…

C++入門一:C++ 編程概述

一、C 語言與 C 的關系:從 “帶類的 C” 到獨立王國 1.1 血緣關系:C 是 C 的 “超級進化版” 起源:C 由 Bjarne Stroustrup 在 1980 年代開發,最初名為 “C with Classes”(帶類的 C),旨在為 …

LLM生成文本的 束搜索參數是什么(Beam Search)

LLM生成文本的 束搜索參數是什么(Beam Search) 束搜索(Beam Search)是一種在序列生成任務(如機器翻譯、文本生成等)中常用的啟發式搜索算法,用于在搜索空間中尋找最優的生成序列。 束搜索的基本概念 在序列生成過程中,每一步都會有多個可能的選擇(即候選標記)。 …

Java-多級排序結合thenComparing()

List<User>,user有個字段有值的時候設置1,沒值就是null,怎么排序根據這個字段排序? 若要對 List<User> 按照某個字段(如 flag,有值時為 1,無值時為 null)排序,可 以使用 ??Comparator?? 結合 null 值處理邏輯。 1. 排序規則說明?? 假設需求是:…

卷積神經網絡(CNN)基礎

目錄 一、應用場景 二、卷積神經網絡的結構 1. 輸入層&#xff08;Input Layer&#xff09; 2. 卷積層&#xff08;Convolutional Layer&#xff09; 3. 池化層&#xff08;Pooling Layer&#xff09; 最大池化&#xff08;max_pooling&#xff09;或平均池化&#xff08;…

Android 中集成 Unity 工程的步驟

在 Adroid 項目中集成 Unity 工程,主要步驟如下: 一、前提條件 1、已有一個 Android 工程項目; 2、Unity 工程已導出為 Android 工程,目錄大概如下: 二、集成步驟 1、在 Android 工程中導入 Unity 工程的 unityLibrary 模塊。 在 Android Studio 中,點擊菜單欄 Fil…

熱Key問題及其解決方案:Redis高并發場景下的性能優化

目錄 一、熱Key問題的本質與影響 1.1 什么是熱Key&#xff1f; 典型熱Key場景&#xff1a; 1.2 熱Key造成的技術挑戰與業務影響 技術層面影響&#xff1a; 業務層面影響&#xff1a; 二、熱Key的科學判定與識別方法 2.1 定量判定標準 QPS集中度指標 資源消耗指標 2.…