策略模式和模板方法模式的區別【面試題】

策略模式和模板方法模式的區別【面試題】

摘要:
策略模式和模板方法模式均屬于行為設計模式,但核心差異顯著。策略模式通過組合實現,支持運行時動態切換完整算法(如支付方式切換),變化維度大;模板方法模式通過繼承實現,固定算法骨架但允許子類定制特定步驟(如文檔生成流程不變,數據源可變),變化維度小。前者由調用方主動選擇策略(控制權在客戶端),后者遵循“好萊塢原則”由父類控制流程調用子類方法(控制權在父類)。選擇依據:需靈活替換整套邏輯用策略模式;需復用流程但微調步驟用模板方法模式。

簡單記憶:

第一,機制不同。模板方法靠繼承,策略靠組合。這意味著模板方法在編譯時就確定了行為擴展(通過子類化)相對變化小,而策略可以在運行時切換,變化的大。

第二,變化維度不同。模板方法變化的是算法中的某些步驟,整體流程不變;策略變化的是整個算法實現。就像做菜,模板方法是固定了“洗菜-切菜-烹飪”流程但允許換刀工,策略則是直接換菜系。

第三,控制方向相反。模板方法由父類控制流程調用子類方法(好萊塢原則),策略是調用方主動選擇策略對象。

策略模式(Strategy Pattern)和模板方法模式(Template Method Pattern)都是行為設計模式,都用于封裝變化的部分,但它們解決問題的角度、實現機制和適用場景有本質區別。以下是兩者核心區別的清晰對比:

1)相同點

策略模式(Strategy Pattern)和模板方法模式(Template Method Pattern)都是行為設計模式,都用于封裝變化的部分,但它們解決問題的角度、實現機制和適用場景有本質區別。以下是兩者核心區別的清晰對比:

2)不同點

2.1)核心目標不同

  • 策略模式:
    替換整個算法
    目標是定義一系列可互換的算法,讓客戶端能根據需要動態切換不同的算法實現,且算法的變化不影響使用它的上下文。
    👉 核心:算法的完整替換。
  • 模板方法模式:
    定義算法的骨架,允許子類重寫特定步驟
    目標是固定一個操作的整體流程結構,僅允許子類修改流程中的某些步驟(變化點),而不改變算法的主干。
    👉 核心:算法骨架不變,步驟細節可變。

2.2)實現機制不同

特性策略模式模板方法模式
關系類型組合(Has-a)繼承(Is-a)
關鍵參與者Context 持有 Strategy 接口的引用抽象類定義 模板方法 + 抽象步驟方法
擴展方式新增 Strategy 實現類創建子類并實現抽象方法/覆蓋鉤子方法
運行時行為可動態切換策略對象子類行為在編譯時確定(通過繼承)
控制流方向Context 委托給策略對象執行父類調用子類方法(“好萊塢原則”)

2.3)變化點不同

  • 策略模式:
    變化的是整個算法邏輯
    例如:支付時在 支付寶信用卡PayPal完全不同的支付邏輯之間切換。
  • 模板方法模式:
    變化的是算法中的某些步驟整體流程固定不變
    例如:文檔生成流程 打開模板->填充數據->保存文件 中,填充數據 的方式可變(填數據庫數據/API數據),但步驟順序不變。

2.4)代碼結構對比

策略模式偽代碼

// 策略接口
interface CompressionStrategy {void compress(File file);
}// 具體策略
class ZipCompression implements CompressionStrategy {void compress(File file) { /* ZIP壓縮邏輯 */ }
}class RarCompression implements CompressionStrategy {void compress(File file) { /* RAR壓縮邏輯 */ }
}// 上下文(組合策略)
class Compressor {private CompressionStrategy strategy;void setStrategy(CompressionStrategy s) { this.strategy = s; }void compressFile(File file) {strategy.compress(file); // 委托給當前策略}
}// 使用:動態切換策略
Compressor compressor = new Compressor();
compressor.setStrategy(new ZipCompression()); // 運行時切換為ZIP
compressor.compressFile(file);

模板方法模式偽代碼

// 抽象類(定義模板骨架)
abstract class DataExporter {// 模板方法 (final 防止子類覆蓋流程)public final void export() {openConnection();fetchData();      // 抽象方法 -> 子類實現transformData();  // 鉤子方法 -> 子類可選覆蓋save();           // 抽象方法 -> 子類實現closeConnection();}protected abstract void fetchData();protected abstract void save();protected void transformData() {} // 默認空實現(鉤子方法)private void openConnection() { /* 通用邏輯 */ }private void closeConnection() { /* 通用邏輯 */ }
}// 具體子類
class CSVExporter extends DataExporter {protected void fetchData() { /* 從DB取數據 */ }protected void save() { /* 存為CSV */ }
}class JSONExporter extends DataExporter {protected void fetchData() { /* 從API取數據 */ }protected void save() { /* 存為JSON */ }protected void transformData() { /* 自定義數據轉換 */ } // 覆蓋鉤子
}// 使用:子類繼承固定流程
DataExporter exporter = new CSVExporter();
exporter.export(); // 執行固定流程+子類實現的步驟

2.5) 適用場景對比

場景策略模式模板方法模式
算法需要動態切換? 支付方式、排序算法、導航策略等? 子類行為在編譯時綁定
多個類有相同流程但不同步驟?? 框架生命周期、文檔生成、ETL流程
避免重復的流程代碼?? 將通用流程抽取到父類
隱藏算法實現細節? 客戶端只依賴策略接口? 子類需知曉抽象步驟
擴展新算法/行為? 新增策略類即可? 新增子類實現抽象步驟
控制子類擴展點?? 用 final 模板方法保護核心流程
關鍵總結:一句話區分
  • 策略模式“換整套方案”
    → 通過組合動態切換完整算法(如支付時換整套支付邏輯)。
  • 模板方法模式“固定流程,定制步驟”
    → 通過繼承固定算法骨架,子類定制某些步驟(如報告生成流程固定,但數據來源和格式可定制)。

💡 簡單記憶

  • 需要運行時靈活替換整個算法?→ 策略模式(組合)。
  • 需要復用固定流程但允許步驟自定義?→ 模板方法模式(繼承)。

喜歡我的文章記得點個在看,或者點贊,持續更新中ing…

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

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

相關文章

從零打造前沿Web聊天室:消息系統

消息存儲系統 聊天室設計,消息存儲系統非常關鍵,因為一開始設計時使用MongoDB,所以后續使用schemma方式存儲。 后端架構:express MongoDB 消息插入策略 在 MongoDB 中設計聊天消息存儲時,插入策略的選擇會影響性能…

[7-01-03].第03節:環境搭建 - 集群架構

RabbitMQ學習大綱 一、使用集群的原因 1.基于以下原因,需要搭建一個 RabbitMQ 集群來解決實際問題 單機版的,無法滿足目前真實應用的要求。如果 RabbitMQ 服務器遇到內存崩潰、機器掉電或者主板故障等情況,會導致rabbitMQ無法提供服務單臺 R…

【vivado】時序分析之Latch pins with no clock

問題: vivado打開時序報告,如下圖 表示存在鎖存器Latch 解決方法: 查看代碼中是否存在狀態機的狀態沒有寫全,或者default中直接寫了null。

如何將 MX Linux 的垂直任務欄面板移到底部

MX Linux 因其速度和較低的資源消耗,比同類其他 Linux 系統更快地獲得了人氣。它默認帶有 Xfce 桌面環境,但任務欄在左側且是垂直的,這對一部分人來說真的非常不舒服且令人煩惱。如果你也有同感,并且也想將 MX Linux 的任務欄自定…

python debug 監控雙下劃線的變量顯示沒有此變量

名稱改寫(Name Mangling) 在Python中,如果你在類中定義一個屬性或方法時以雙下劃線開頭(例如__attribute),Python會自動對其進行名稱改寫。名稱改寫實際上是在屬性或方法名前加上類名,以避免子…

list使用及模擬

01. list介紹 list是支持常數時間內任意位置插入刪除的序列容器,具備雙向迭代能力。其底層為雙向鏈表結構,各元素存于獨立節點,通過指針指向前后元素。與forward_list的主要區別:后者是單鏈表,僅支持單向迭代,結構更簡單高效。相比array、vector、deque等序列容器,list在…

NLP基礎與詞嵌入:讓AI理解文字(superior哥深度學習系列第13期)

13_NLP基礎與詞嵌入:讓AI理解文字 superior哥深度學習系列第十三篇 從像素到文字,從視覺到語言——讓AI跨越認知的橋梁 🎯 前言:當AI學會"讀懂"文字 各位小伙伴們,歡迎來到superior哥深度學習系列的第十三篇…

【時時三省】(C語言基礎)關于變量的聲明和定義

山不在高,有仙則名。水不在深,有龍則靈。 ----CSDN 時時三省 可能有些人弄不清楚定義與聲明有什么區別,它們是否是一回事。有人認為聲明就是定義,有人認為只有賦了值的才是定義。在C語言的學習中,關于定義與聲明這兩個…

Java 時間處理指南:從“踩坑”到“填坑”實戰

🔥「炎碼工坊」技術彈藥已裝填! 點擊關注 → 解鎖工業級干貨【工具實測|項目避坑|源碼燃燒指南】 場景問題:訂單處理系統的時間計算 假設你正在開發一個電商訂單系統,需要解決以下問題: 用戶下單后,需在…

基于Java的Excel列數據提取工具實現

摘要:本文介紹了一個使用Java語言開發的Excel列數據提取工具,該工具借助Apache POI庫實現對Excel文件的讀取與特定列數據提取功能。通過用戶輸入文件路徑與列名,程序可從指定Excel文件中提取相應列的數據并展示,同時詳細闡述了關鍵…

關于人工智能未來的趨勢

學而不思則罔 翻譯:使用深度學習、強化學習卻不用專家系統,就會產生幻覺。 思而不學則殆 翻譯:只有專家系統邏輯推理,但是不用大模型更新知識,就無法發展下去了。 因此,未來智能的范式應該是: …

Java八股文——MySQL「性能調優篇」

MySQL的EXPLAIN有什么作用? 面試官您好,EXPLAIN命令是我在進行SQL性能優化時,使用最頻繁、也最重要的一個工具。 它的核心作用可以一句話概括:模擬MySQL的查詢優化器來執行一條SQL語句,并向我們展示出它最終決定采用…

win打印機共享處理

win打印機共享處理 軟件鏈接 無法啟動Print Spooler服務錯誤193:0xc1的解決方案主要涉及修復服務依賴關系、清理打印緩存及修復系統文件?。該錯誤通常由系統文件損壞、注冊表配置異常或依賴服務未啟動導致,可通過以下步驟系統化解決。?? 解決方法:替換…

C++ map代碼練習 1、2、priority_queue基礎概念、對象創建、數據插入、獲取堆頂、出隊操作、大小操作,自定義結構、代碼練習 1 2

map代碼練習1&#xff0c;對應力扣 兩個數據的交集&#xff0c;代碼見下 class Solution { public:vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {map<int, int> cnt;vector<int> ans;for(int i0; i<nums1.size(…

三天沖刺《編譯原理》——筆記(一)

點關注不迷路喲。你的點贊、收藏&#xff0c;一鍵三連&#xff0c;是我持續更新的動力喲&#xff01;&#xff01;&#xff01; 持續關注我~~~主頁&#xff0c;查看更多內容喲&#xff08;希望你能在這里有所收獲&#x1f92d;&#xff09;。點關注&#xff0c;不迷路&#xf…

代理模式Proxy Pattern

模式定義 給某一個對象提供一個代理&#xff0c;并由代理對象控制對原對象的引用 對象結構型模式 模式結構 Subject&#xff1a;抽象主題角色Proxy&#xff1a;代理主題角色RealSubject&#xff1a;真實主題角色 代理類實現代碼 public class Proxy implements Subject {p…

基于YOLOv11與單目測距的實戰教程:從目標檢測到距離估算

引言 在計算機視覺領域&#xff0c;目標檢測與距離估算的結合是自動駕駛、機器人導航等場景的關鍵技術。本文將以YOLOv8模型為核心&#xff0c;結合單目相機的幾何模型&#xff0c;實現對視頻中目標的實時檢測與距離估算。代碼參考自單目測距原理博客&#xff0c;并通過實踐驗…

代碼生成器使用原理以及使用方法

代碼生成器使用原理以及使用方法 版本號&#xff1a;1.0 二Ο二五年二月 目錄 文檔介紹 1.1編寫目的 1.2文檔范圍 1.3讀者對象 系統設計 2.1設計目標 2.2設計思路 2.3代碼實現原理 使用方法 3.1如何使用 3.2如何修改&#xff1f; 對原程序的bug修改及簡…

STM32標準庫-I2C通信

文章目錄 一、I2C通信1.1 I2C1.2硬件電路1.3I2C時序基本單元1.4I2C時序 二、MPU60502.1簡介2.2MPU6050參數2.3硬件電路2.4MPU6050框圖 三、I2C外設(硬件)3.1簡介3.2I2C框圖3.3I2C基本結構3.4主機發送3.5主機接收3.6軟件/硬件波形對比1. 時序精度2. 信號穩定性3. 速率與效率4. 波…

使用 Azure LLM Functions 與 Elasticsearch 構建更智能的查詢體驗

作者&#xff1a;來自 Elastic Jonathan Simon 及 James Williams 試用這個示例房地產搜索應用&#xff0c;它結合了 Azure Gen AI LLM Functions 與 Elasticsearch&#xff0c;提供靈活的混合搜索結果。在 GitHub Codespaces 中查看逐步配置和運行該示例應用的方法。 更多閱讀…