從C++編程入手設計模式——策略設計模式

從C++編程入手設計模式——策略設計模式

? 在我們平時寫程序的過程中,經常會遇到這樣的情況:一個對象的某個功能可以有多種實現方式,而且可能會根據不同的場景切換這些方式。比如一只動物可以發出不同的叫聲,一個排序器可以使用不同的排序算法,一個支付系統可以接入不同的支付平臺。這時候,我們就可以使用“策略設計模式”。

? 策略策略,實際上就是做一個事情的策略方法。換而言之,這個設計模式用在哪些應付解決方案多變的場景。我們把某個行為(比如“怎么叫”“怎么排序”“怎么支付”)封裝成一個獨立的策略對象,讓原本需要執行這個行為的類把這個行為委托給策略對象來完成。這樣,我們可以很方便地替換行為、擴展行為,而不需要修改原來的類。

#include <iostream>
#include <functional>class Context {
public:void setStrategy(std::function<void()> strat) {strategy = strat;}void executeStrategy() {if (strategy) {strategy();}}private:std::function<void()> strategy;
};

? 如你所見,這就是把我們具體的實現行為替換成給定接口的函數指針。

策略模式的結構

從設計的角度來看,策略模式通常包含三部分:

  1. 策略接口:定義某個行為的抽象,比如“排序算法”或“支付方式”。
  2. 具體策略:不同的實現,比如“冒泡排序”、“支付寶支付”。
  3. 上下文類:也就是使用這些策略的地方,內部持有一個策略接口的對象,通過它來執行行為。

什么場景適合用策略模式

  • 有多個算法可以選擇,比如不同的排序方法、路徑規劃算法等。
  • 行為需要根據不同條件動態變化,比如不同平臺上的繪圖方式。
  • 不同業務場景下執行邏輯不同,比如不同國家的稅率計算方式。

和 if-else 的區別在哪?

很多人會說:“我直接寫一堆 if-elseswitch 不也可以嗎?”確實可以,但這樣做有兩個問題:

  • 每增加一種新行為就要改動原來的代碼,不利于維護。
  • 所有實現都混在一起,導致類越來越臃腫,不利于閱讀和測試。

而使用策略模式,每個行為單獨封裝起來,不但代碼更清晰,還能獨立測試每一個策略實現。

一個例子

需求:設計一個動物模擬器,支持不同動物發出不同的叫聲。使用策略模式實現動物叫聲的可變換(例如狗叫 “汪汪”,貓叫 “喵喵”)。

要求

  • 定義 ISoundStrategy 接口,有一個 makeSound() 函數。
  • 實現 DogSoundStrategyCatSoundStrategy 等具體策略類。
  • 定義 Animal 類,持有一個 ISoundStrategy*
  • 允許運行時更換動物的叫聲策略。

示例輸出

Dog: 汪汪
Cat: 喵喵
Dog changes to cat sound: 喵喵

筆者沒有嚴格的實現這個題目的要求,但是您可以參考一下:

modern-cpp-patterns-playground/Strategy/AnimalSound at main · Charliechen114514/modern-cpp-patterns-playground

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

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

相關文章

網頁中調用自定義字體可以通過 ?CSS? 的 @font-face 規則實現

以下是詳細方法&#xff1a; ?1. 使用系統默認字體? 如果只是希望指定字體&#xff0c;可以直接使用 font-family&#xff1a; body { font-family: "Microsoft YaHei", "PingFang SC", sans-serif; /* 中英文適配 */ } ?2. 使用自定義字體&…

[CVPR 2025] DeformCL:基于可變形中心線的3D血管提取新范式

CVPR 2025 | DeformCL&#xff1a;基于可變形中心線的3D血管提取新范式 論文信息 標題&#xff1a;DeformCL: Learning Deformable Centerline Representation for Vessel Extraction in 3D Medical Image作者&#xff1a;Ziwei Zhao, Zhixing Zhang, Yuhang Liu, 等單位&…

BeckHoff <---> Keyence (LJ-X8000) 2D相機 Profinet 通訊

目錄 ?編輯 一、 設備介紹 1、產品特點 2、控制器選擇 3、應用領域 二、PLC通訊接口配置 1、PLC添加GSDML文件 2、定義輸入3、變量實例化 3、定義輸出變量實例化 三、設備通訊接口數據類型定義 1、定義全局結構體數據 2、定義 INput Decode結構體數據 四、通訊…

electron在單例中實現雙擊打開文件,并重復打開其他文件

單實例的思路 首次通過雙擊文件打開應用 將filePath傳給render 使用中的應用&#xff0c;再次雙擊打開文件 第一個實例創建時&#xff0c;同時創建一個通信服務器net.createServer()第二個實例創建時&#xff0c;連接第一個服務器net.createConnection()將再次打開的filePath傳…

一、基礎架構層:高性能引擎基石

1. ECS架構工業級實現 // EnTT實戰示例&#xff1a;導彈系統組件定義 struct Position { vec3 value; }; struct Velocity { vec3 value; }; struct ExplodeWhen { float distance; };entt::registry registry;// 實體創建與組件綁定 auto missile registry.create(); regist…

rockylinuxapache和Linux服務配置

目錄 apache nginx 反向代理配置[rootk8s2 ~]# [rootk8s2 ~]# cat /etc/nginx/conf.d/webserver.confserver { listen 80; server_name www.sxy1.com; location / { root /var/www/html; index index.html; } location /py/{ …

ai 幻覺

ai幻覺: 感知人類觀察者不存在或無法感知的模式或對象&#xff0c;從而產生無意義或完全不準確的輸出 有時 AI 算法會生成并非基于訓練數據的輸出結果&#xff0c;繼而被轉換器錯誤解碼或不遵循任何可識別的模式。換句話說&#xff0c;它會在給出響應時“產生幻覺” 致因:訓練…

freeRTOS移植實驗

提示&#xff1a;文章 文章目錄 前言一、背景第6章節 二、2.12.2 三、3.1 總結 前言 前期疑問&#xff1a; 本文目標&#xff1a; 一、背景 在家里先使用野火網盤資料里的freeRTOS源碼&#xff0c;網盤里是v9.0.0。 J:\野火\STM32F103ZET6_霸道開發板\A盤&#xff08;資料盤…

食品加工溫控場景:PROFIBUS轉MODBUS的溫控表連接規范

在現代的工業自動化領域里&#xff0c;實現不同通信協議設備間無縫對接的技術日益受到重視。這不僅關乎系統整合性和效率的提升&#xff0c;更是實現復雜工業過程自動化的必經之路。特別是在眾多的通信協議中&#xff0c;MODBUS和PROFIBUS這兩種廣泛使用的協議因其各自的優勢而…

【動態規劃】回文串(二)

&#x1f4dd;前言說明&#xff1a; 本專欄主要記錄本人的動態規劃算法學習以及LeetCode刷題記錄&#xff0c;按專題劃分每題主要記錄&#xff1a;&#xff08;1&#xff09;本人解法 本人屎山代碼&#xff1b;&#xff08;2&#xff09;優質解法 優質代碼&#xff1b;&…

Ubuntu22.04.5 桌面版然后安裝 VMware 17

安裝 VMware 需要 GCC 12版本 標題通過 PPA 安裝 這是最簡單的方法&#xff0c;適用于大多數 Ubuntu 版本。 步驟 1&#xff1a;添加 PPA 倉庫 sudo apt update sudo apt install software-properties-common sudo add-apt-repository ppa:ubuntu-toolchain-r/test sudo apt…

深入解析 MySQL 架構:從基礎到高級

MySQL 是一款廣泛使用的開源關系型數據庫管理系統&#xff0c;以其高性能、可靠性和靈活性而聞名。無論是小型創業公司還是大型企業&#xff0c;MySQL 都是許多應用程序的首選數據庫解決方案。本文將深入探討 MySQL 的架構設計&#xff0c;幫助讀者更好地理解其內部工作機制&am…

BACnet協議移植適配實現BACnet/IP和BACnet MSTP相關功能

1、從GitHub或者其他網站下載最新的協議棧源碼 源碼結構如圖所示&#xff1a; 其中src是協議棧源碼&#xff0c;可直接拿來使用&#xff0c;apps里面是一些功能的應用示例&#xff0c;有BACnet IP&#xff0c;BACnet MSTP&#xff0c;BACnet Router等功能。 2、協議棧移植完成…

Ubuntu 22.04.1 LTS 離線安裝Docker(最快方法,僅需一個壓縮文件和兩個腳本)

作者親測&#xff1a;親測有效無bug。 利用ubuntu22.04下載完docker-27.4.1.tgz,然后按照下面方法安裝。選擇sudo方法。 tips:這個ubuntu22.04是遷移后的服務器的版本&#xff0c;不是遷移前的版本。 下載 下載地址 : https://download.docker.com/linux/static/stable/x86_…

Tkinter --按鈕點擊事件應用場景

第二章 事件處理 目錄 第二章 事件處理 四、事件處理 4.1 按鈕點擊事件 4.1.1信息展示類場景 1. 靜態文本說明 ?編輯 2. 動態狀態顯示 4.1.2.界面美化與裝飾 1. 圖像 / 圖標展示 ?編輯 2. 分隔與布局輔助 4.1.3 交互反饋與提示 1. 操作結果提示 2. 幫助與說明文本…

計算機網絡學習筆記:TCP流控、擁塞控制

文章目錄 前言一、TCP流量控制1.1、案例&#xff1a;三次流量控制1.2、持續計時器 二、TCP擁塞控制2.1、擁塞控制的指標2.2、慢開始算法和擁塞避免算法2.3、快重傳算法和快恢復算法2.4、練習 三、TCP擁塞控制與網際層擁塞控制總結 前言 TCP協議中的流量和擁塞&#xff0c;是兩個…

【Linux】Tomcat搭建

前言 Tomcat Tomcat 服務器是一個免費的開放源代碼的Web 應用服務器&#xff0c;屬于輕量級應用服務器&#xff0c;在中小型系統和并發訪問用戶不是很多的場合下被普遍使用&#xff0c;是開發和調試JSP 程序的首選。 JSP JSP是一種跨平臺的動態網頁技術標準&#xff0c;可以…

Ajax 核心知識點全面總結

文章目錄 Ajax 核心知識點全面總結一、Ajax 基礎概念1、定義2、核心特點 二、Ajax 工作原理與核心組件1、工作流程2、XMLHttpRequest&#xff08;XHR&#xff09;對象 三、Ajax 請求方法與參數1、常見請求方法2、請求參數處理 四、Ajax 異步與錯誤處理1、異步處理2、錯誤處理 五…

SpinFlowSim:用于癌癥組織學信息驅動的擴散MRI微血管映射的血流模擬框架|文獻速遞-深度學習醫療AI最新文獻

Title 題目 SpinFlowSim: A blood flow simulation framework for histology-informeddiffusion MRI microvasculature mapping in cancer SpinFlowSim&#xff1a;用于癌癥組織學信息驅動的擴散MRI微血管映射的血流模擬框架 01 文獻速遞介紹 在擴散磁共振成像&#xff08…

量化面試綠皮書:21. 拋硬幣游戲

文中內容僅限技術學習與代碼實踐參考&#xff0c;市場存在不確定性&#xff0c;技術分析需謹慎驗證&#xff0c;不構成任何投資建議。 21. 拋硬幣游戲 兩個賭徒正在玩一個拋硬幣游戲。 賭徒A有(n1)枚均勻硬幣&#xff0c;賭徒B有n枚均勻硬幣。 Q: 如果兩人同時拋擲所有硬幣&a…