策略模式的C++實現示例

核心思想

策略模式是一種行為型設計模式,它定義了一系列算法,并將每個算法封裝在獨立的類中,使得它們可以互相替換。策略模式讓算法的變化獨立于使用它的客戶端,從而使得客戶端可以根據需要動態切換算法,而不需要修改其代碼。策略模式的核心是將算法與使用算法的客戶端解耦,使得算法可以獨立于客戶端變化。

**Context:**持有一個策略對象的引用,負責調用策略的具體實現。
**Strategy:**定義所有支持的算法的公共接口。
**ConcreteStrategy:**實現Strategy接口,提供具體的算法實現。

使用場景

多種算法切換:如排序算法(快速排序、冒泡排序等)或支付方式(信用卡、支付寶等)。
避免條件語句:當代碼中有大量條件分支用于選擇不同行為時,可以用策略模式替代。
算法復用:當多個類需要共享相同的行為,但行為的具體實現不同時。
動態切換行為:如游戲中的角色在不同狀態下使用不同的攻擊策略。
測試與調試:策略模式可以方便地替換算法的實現,便于測試和調試。

解決的問題

代碼重復問題:
如果多個類使用相同的算法,但算法的實現分散在各處,會導致代碼重復。策略模式將算法集中管理,避免重復。

緊耦合問題:
在傳統設計中,算法直接嵌入在客戶端代碼中,導致客戶端與算法緊耦合。策略模式通過將算法抽象為接口,解耦了客戶端和具體算法。

擴展性問題:
新增算法時,需要修改客戶端代碼。策略模式允許動態添加新算法,而無需修改現有代碼。

條件分支問題:
當代碼中有大量條件分支用于選擇不同行為時,策略模式可以將其替換為對象的多態調用,使代碼更清晰。

優點

**開閉原則:**新增算法無需修改現有代碼,只需添加新的策略類。
**解耦:**將算法的實現與使用分離,提高代碼的靈活性和可維護性。
**復用性:**策略類可以在不同上下文中復用。
**簡化測試:**每個策略類可以獨立測試。

缺點

**類數量增加:**每個算法都需要一個單獨的類,可能導致類的數量增多。
**客戶端需要了解策略:**客戶端需要知道有哪些策略,并選擇合適的策略。
**性能開銷:**策略模式可能引入額外的對象創建和調用開銷。

示例代碼

如下代碼中,Context類(即客戶端)是穩定、可以不變的,變化的是策略,而策略是根據運行時的實際情況來選擇的。通過繼承Strategy類并重寫execute()接口實現策略的擴展。

#include <iostream>
#include <memory>// 抽象策略接口
class Strategy {
public:virtual void execute() const = 0;virtual ~Strategy() = default;  // 虛析構函數,確保正確釋放資源
};// 具體策略A
class ConcreteStrategyA : public Strategy {
public:void execute() const override {std::cout << "執行策略A" << std::endl;}
};// 具體策略B
class ConcreteStrategyB : public Strategy {
public:void execute() const override {std::cout << "執行策略B" << std::endl;}
};// 上下文類,持有策略對象并調用其方法
class Context {
private:std::unique_ptr<Strategy> strategy;  // 使用智能指針管理策略對象public:// 構造函數,允許傳入策略對象Context(std::unique_ptr<Strategy> s) : strategy(std::move(s)) {}// 設置策略void setStrategy(std::unique_ptr<Strategy> s) {strategy = std::move(s);}// 執行策略void executeStrategy() const {if (strategy) {strategy->execute();} else {std::cout << "未設置策略" << std::endl;}}
};int main() {// 創建上下文對象,并初始化為策略AContext context(std::make_unique<ConcreteStrategyA>());context.executeStrategy();  // 輸出: 執行策略A// 動態切換到策略Bcontext.setStrategy(std::make_unique<ConcreteStrategyB>());context.executeStrategy();  // 輸出: 執行策略Breturn 0;
}

代碼說明

?Strategy:抽象策略接口,定義了所有具體策略類必須實現的方法execute()。
?ConcreteStrategyA? 和 ?ConcreteStrategyB:具體策略類,分別實現了不同的算法或行為。
?Context:上下文類,持有一個策略對象的引用,并提供了設置策略和執行策略的方法。
?智能指針:使用std::unique_ptr管理策略對象的生命周期,避免內存泄漏。

運行結果

執行策略A
執行策略B

總結

通過策略模式,我們可以將算法的實現與使用算法的環境解耦,使得算法可以獨立于客戶端代碼進行擴展和修改。這種設計模式特別適用于需要動態切換算法的場景。

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

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

相關文章

Loki+Promtail+Grafana監控K8s日志

在現代云原生架構中&#xff0c;監控與日志管理對于確保系統穩定性和可靠性至關重要。Kubernetes&#xff08;K8s&#xff09;作為當下流行的容器編排平臺&#xff0c;對日志的監控管理需求尤為突出。Loki, Promtail 和 Grafana 構成了一套強大的日志監控解決方案&#xff0c;它…

Git 批量合并 Commit 并且保留之前的 Commit 快速實現的思路

文章目錄 需求Rebase / Pick / squashVim 的快速全局字符串替換 需求 我想把如下的提交 commit&#xff0c;變成一個 Commit&#xff0c;并且合并這些 Commit 的消息到一個節點 Rebase / Pick / squash 我合并到 5e59217 這個hash 上&#xff0c;這樣合并后會保留兩個 Commit…

基于海思soc的智能產品開發(芯片sdk和linux開發關系)

【 聲明&#xff1a;版權所有&#xff0c;歡迎轉載&#xff0c;請勿用于商業用途。 聯系信箱&#xff1a;feixiaoxing 163.com】 隨著國產化芯片的推進&#xff0c;在soc領域&#xff0c;越來越多的項目使用國產soc芯片。這些soc芯片&#xff0c;通常來說運行的os不是linux&…

將數據庫結構化數據整合到RAG問答中的方式

**將數據庫&#xff08;結構化數據&#xff09;接入 RAG&#xff08;Retrieval-Augmented Generation&#xff09;**的常見方式&#xff0c;并分別說明其實現方法、優點與缺點。 方式一&#xff1a;LLM 自動生成查詢語句&#xff08;SQL/NoSQL&#xff09;直接訪問數據庫 方法…

論壇系統測試報告

目錄 一、項目背景二、論壇系統測試用例思維導圖三、論壇系統測試3.1界面測試3.2登陸測試3.3主頁測試3.4個人中心測試 四、自動化測試腳本4.1配置驅動4.2創建瀏覽器類4.3功能測試4.3.1登陸測試4.3.2注冊測試4.3.3主頁測試4.3.4帖子編輯4.3.5運行主代碼 五、BUG分析六、測試總結…

python量化交易——金融數據管理最佳實踐——使用qteasy大批量自動拉取金融數據

文章目錄 使用數據獲取渠道自動填充數據QTEASY數據拉取功能數據拉取接口refill_data_source()數據拉取API的功能特性多渠道拉取數據實現下載流量控制實現錯誤重試日志記錄其他功能 qteasy是一個功能全面且易用的量化交易策略框架&#xff0c; Github地址在這里。使用它&#x…

后端架構模式之-BFF(Backend-For-Frontend)

Backend-for-Frontend&#xff08;BFF&#xff09; 的概念與意義 1. 什么是 Backend-for-Frontend&#xff08;BFF&#xff09;&#xff1f; Backend-for-Frontend&#xff08;簡稱 BFF&#xff09;是一種后端架構模式&#xff0c;它為特定的前端應用&#xff08;Web、移動端…

upload-labs靶場 1-21通關

目錄 1.Pass-01 前端繞過 分析 解題 2.Pass-02 服務器端檢測--修改IMME 分析 解題 3.Pass-03 黑名單繞過 分析 解題 4.Pass-04 .htaccess繞過 分析 解題 5.Pass-05 . .繞過和.user.ini繞過 分析 解題 6.Pass-06 大小寫繞過 分析 解題 7.Pass-07 空格繞過 分…

信貸風控系統架構設計

設計一個信貸風控系統需要綜合考慮業務需求、技術架構、數據治理、合規安全等多個維度。以下是從頂級Java架構師視角的系統設計方案&#xff0c;分模塊詳細說明&#xff1a; 一、系統架構設計原則 高可用性&#xff1a;7x24小時服務&#xff0c;多機房容災。低延遲&#xff1a…

Ubuntu20.04 在離線機器上安裝 NVIDIA Container Toolkit

步驟 1.下載4個安裝包 Index of /nvidia-docker/libnvidia-container/stable/ nvidia-container-toolkit-base_1.13.5-1_amd64.deb libnvidia-container1_1.13.5-1_amd64.deb libnvidia-container-tools_1.13.5-1_amd64.deb nvidia-container-toolkit_1.13.5-1_amd64.deb 步…

【工具】COME對比映射學習用于scRNA-seq數據的空間重構

介紹 單細胞RNA測序&#xff08;scRNA-seq&#xff09;能夠在單細胞分辨率下實現高通量轉錄組分析。固有的空間位置對于理解單細胞如何協調多細胞功能和驅動疾病至關重要。然而&#xff0c;在組織分離過程中&#xff0c;空間信息常常丟失。空間轉錄組學&#xff08;ST&#xf…

Idea配置注釋模板

一、配置類注釋模板 打開IDEA&#xff0c;打開settings(快捷鍵&#xff1a;Ctrl Alt s)&#xff0c;選擇Editor&#xff0c;找到File and Code Templates 這里以設置class文件為例&#xff0c;點擊Class&#xff0c;在右側配置以下內容 #if (${PACKAGE_NAME} && $…

pytorch高可用的設計策略和集成放大各自功能

在使用 PyTorch 編寫模型時,為確保模型具備高可用性,可從模型設計、代碼質量、訓練過程、部署等多個方面采取相應的方法,以下為你詳細介紹: 模型設計層面 模塊化設計 實現方式:將模型拆分成多個小的、獨立的模塊,每個模塊負責特定的功能。例如,在一個圖像分類模型中,可…

從開源大模型工具Ollama存在安全隱患思考企業級大模型應用如何嚴守安全紅線

近日&#xff0c;國家網絡安全通報中心通報大模型工具Ollama默認配置存在未授權訪問與模型竊取等安全隱患&#xff0c;引發了廣泛關注。Ollama作為一款開源的大模型管理工具&#xff0c;在為用戶提供便捷的同時&#xff0c;卻因缺乏有效的安全管控機制&#xff0c;存在數據泄露…

初識Qt · 信號與槽 · 基礎知識

目錄 前言&#xff1a; 信號和槽初識 兩個問題 前言&#xff1a; 本文我們正式開始介紹信號與槽這個概念&#xff0c;在談及Qt中的信號與槽這個概念之前&#xff0c;我們不妨回顧一下Linux中的信號&#xff0c;比如發生了除0錯誤&#xff0c;OS就會給該進程發送一個信號&am…

Kotlin 5種單例模式

在Kotlin中實現單例模式有多種方法&#xff0c;以下是幾種常見的方法&#xff1a; 餓漢式 餓漢式是最簡單的一種實現方式&#xff0c;在類加載時就完成了實例的初始化。 //餓漢式 object Singleton1 {fun printMessage() {println("餓漢式")} }懶漢式 懶漢式是延遲…

探秘基帶算法:從原理到5G時代的通信變革【一】引言

文章目錄 一、引言1.1 研究背景與意義1.2 研究目的與方法1.3 研究內容與創新點 本博客為系列博客&#xff0c;主要講解各基帶算法的原理與應用&#xff0c;包括&#xff1a;viterbi解碼、Turbo編解碼、Polar編解碼、CORDIC算法、CRC校驗、FFT/DFT、QAMtiaozhi/解調、QPSK調制/解…

C/C++輸入輸出(1)

1.getchar和putchar 1.1getchar() 函數原型&#xff1a; 1 int getchar(void); getchar()函數返回用戶從鍵盤輸入的字符&#xff0c;使用時不帶有任何參數。 程序運行到這個命令就會暫停&#xff0c;等待用戶從鍵盤輸入&#xff0c;等同于使用cin或scanf()方法讀取一個字符…

【消息隊列】數據庫的數據管理

1. 數據庫的選擇 對于當前實現消息隊列這樣的一個中間件來說&#xff0c;具體要使用哪個數據庫&#xff0c;是需要稍作考慮的&#xff0c;如果直接使用 MySQL 數據庫也是能實現正常的功能&#xff0c;但是 MySQL 也是一個客戶端服務器程序&#xff0c;也就意味著如果想在其他服…

飛機大戰lua迷你世界腳本

-- 迷你世界飛機大戰 v1.2 -- 星空露珠工作室制作 -- 最后更新&#xff1a;2024年1月 ----------------------------- -- 迷你世界API適配配置 ----------------------------- local UI { BASE_ID 7477478487091949474-22856, -- UI界面ID ELEMENTS { BG 1, -- 背景 BTN_LE…