策略模式及優化

策略模式(Strategy Pattern)是一種行為設計模式,其核心思想是將算法的定義與使用分離,使算法可以獨立于客戶端進行變化。它通過定義一系列算法,將每個算法封裝到獨立的類中,并使它們可以互相替換,從而讓算法的變化不會影響到使用算法的客戶端。

介紹

策略模式的核心組件
  1. 策略接口(Strategy Interface)
    定義所有具體策略必須實現的公共方法,通常是一個抽象類或接口。例如,在排序場景中,策略接口可能定義sort()方法。

  2. 具體策略(Concrete Strategies)
    實現策略接口的具體算法類。例如:BubbleSortQuickSortMergeSort等。

  3. 上下文(Context)
    持有一個策略接口的引用,負責根據需要動態切換具體策略。上下文不直接實現算法,而是將工作委托給策略對象。

  4. 客戶端(Client)
    負責創建具體策略并將其注入到上下文中,控制策略的選擇邏輯。

策略模式的特點
  1. 可替換性
    客戶端可以在運行時動態切換策略,無需修改上下文代碼。

  2. 開閉原則
    新增策略只需實現接口,無需修改現有代碼,符合“對擴展開放,對修改關閉”的原則。

  3. 解耦算法
    算法的實現細節被封裝在具體策略中,客戶端無需關心其內部邏輯。

  4. 消除條件語句
    避免使用大量if-elseswitch語句來選擇算法,使代碼更簡潔。

適用場景
  1. 多種算法選擇:當一個問題有多種解決算法,且需要在運行時動態切換時。
  2. 避免條件語句:替代大量的if-elseswitch語句,使代碼更清晰。
  3. 算法封裝:將算法的實現細節與使用算法的客戶端代碼分離。

實現

#include <iostream>
#include <memory>
#include <string>// 策略接口:定義算法族
class SortStrategy {
public:virtual ~SortStrategy() = default;virtual void sort(std::vector<int>& data) const = 0;
};// 具體策略:冒泡排序
class BubbleSort : public SortStrategy {
public:void sort(std::vector<int>& data) const override {std::cout << "使用冒泡排序..." << std::endl;// 冒泡排序實現int n = data.size();for (int i = 0; i < n - 1; ++i) {for (int j = 0; j < n - i - 1; ++j) {if (data[j] > data[j + 1]) {std::swap(data[j], data[j + 1]);}}}}
};// 具體策略:快速排序
class QuickSort : public SortStrategy {
public:void sort(std::vector<int>& data) const override {std::cout << "使用快速排序..." << std::endl;// 快速排序實現quickSort(data, 0, data.size() - 1);}private:void quickSort(std::vector<int>& data, int left, int right) const {if (left < right) {int pivotIndex = partition(data, left, right);quickSort(data, left, pivotIndex - 1);quickSort(data, pivotIndex + 1, right);}}int partition(std::vector<int>& data, int left, int right) const {int pivot = data[right];int i = left - 1;for (int j = left; j < right; ++j) {if (data[j] <= pivot) {++i;std::swap(data[i], data[j]);}}std::swap(data[i + 1], data[right]);return i + 1;}
};// 上下文:維護一個策略引用
class Sorter {
private:std::unique_ptr<SortStrategy> strategy;public:explicit Sorter(std::unique_ptr<SortStrategy> strategy): strategy(std::move(strategy)) {}void setStrategy(std::unique_ptr<SortStrategy> strategy) {this->strategy = std::move(strategy);}void performSort(std::vector<int>& data) const {if (strategy) {strategy->sort(data);} else {std::cout << "未設置排序策略" << std::endl;}}
};// 客戶端代碼
int main() {std::vector<int> data = {5, 4, 3, 2, 1};// 使用冒泡排序Sorter sorter(std::make_unique<BubbleSort>());sorter.performSort(data);for (int num : data) {std::cout << num << " ";}std::cout << std::endl;// 切換為快速排序data = {5, 4, 3, 2, 1};sorter.setStrategy(std::make_unique<QuickSort>());sorter.performSort(data);for (int num : data) {std::cout << num << " ";}std::cout << std::endl;return 0;
}
應用場景
  1. 排序算法切換:根據數據規模選擇冒泡排序、快速排序等。
  2. 支付方式:電商系統中支持支付寶、微信、銀行卡等多種支付方式。
  3. 壓縮算法:文件壓縮工具支持ZIP、RAR、7Z等不同壓縮算法。
  4. 游戲AI:不同難度的敵人使用不同的行為策略。
  5. 加密算法:安全系統中動態選擇加密方式(MD5、SHA-256等)。
策略模式與其他模式的對比
模式核心區別
策略模式算法的定義與使用分離,強調運行時動態切換。
狀態模式行為隨內部狀態變化而變化,狀態轉換通常由上下文觸發。
工廠模式專注于對象的創建,而不涉及對象的行為。

策略模式優化(注冊機制和反射)

優化措施
  1. 策略工廠與注冊機制

    • StrategyFactory 使用單例模式管理策略的創建
    • 通過 registerStrategy 方法注冊策略名稱和對應的工廠函數
    • StrategyRegistrar 模板類用于靜態注冊,避免手動調用注冊函數
  2. 反射機制

    • 使用 std::function 和 lambda 表達式實現類型擦除
    • 通過字符串名稱動態創建策略對象
    • 靜態注冊確保在程序初始化時完成所有策略的注冊
  3. Sorter類改進

    • 在構造函數中初始化所有策略實例
    • 使用 std::unordered_map 管理策略對象
    • 通過 setStrategy 方法動態切換當前使用的策略
    • 所有策略對象僅創建一次,提高性能
#include <iostream>
#include <vector>
#include <memory>
#include <string>
#include <unordered_map>
#include <functional>// 策略接口
class SortStrategy {
public:virtual ~SortStrategy() = default;virtual void sort(std::vector<int>& data) const = 0;
};// 具體策略:冒泡排序
class BubbleSort : public SortStrategy {
public:void sort(std::vector<int>& data) const override {std::cout << "使用冒泡排序..." << std::endl;int n = data.size();for (int i = 0; i < n - 1; ++i) {for (int j = 0; j < n - i - 1; ++j) {if (data[j] > data[j + 1]) {std::swap(data[j], data[j + 1]);}}}}
};// 具體策略:快速排序
class QuickSort : public SortStrategy {
public:void sort(std::vector<int>& data) const override {std::cout << "使用快速排序..." << std::endl;quickSort(data, 0, data.size() - 1);}private:void quickSort(std::vector<int>& data, int left, int right) const {if (left < right) {int pivotIndex = partition(data, left, right);quickSort(data, left, pivotIndex - 1);quickSort(data, pivotIndex + 1, right);}}int partition(std::vector<int>& data, int left, int right) const {int pivot = data[right];int i = left - 1;for (int j = left; j < right; ++j) {if (data[j] <= pivot) {++i;std::swap(data[i], data[j]);}}std::swap(data[i + 1], data[right]);return i + 1;}
};// 策略工廠:負責創建策略實例
class StrategyFactory {
public:static StrategyFactory& getInstance() {static StrategyFactory instance;return instance;}void registerStrategy(const std::string& name, std::function<std::unique_ptr<SortStrategy>()> factory) {factories[name] = factory;}std::unique_ptr<SortStrategy> createStrategy(const std::string& name) {auto it = factories.find(name);if (it != factories.end()) {return it->second();}return nullptr;}private:StrategyFactory() = default;std::unordered_map<std::string, std::function<std::unique_ptr<SortStrategy>()>> factories;
};// 策略注冊表:靜態注冊策略
template<typename T>
struct StrategyRegistrar {StrategyRegistrar(const std::string& name) {StrategyFactory::getInstance().registerStrategy(name, []() {return std::make_unique<T>();});}
};// 上下文:維護策略并提供排序功能
class Sorter {
public:Sorter() {strategies["bubble"] = StrategyFactory::getInstance().createStrategy("bubble");strategies["quick"] = StrategyFactory::getInstance().createStrategy("quick");currentStrategy = strategies["bubble"].get();}void setStrategy(const std::string& name) {auto it = strategies.find(name);if (it != strategies.end()) {currentStrategy = it->second.get();} else {std::cout << "未找到策略: " << name << std::endl;}}void performSort(std::vector<int>& data) const {if (currentStrategy) {currentStrategy->sort(data);} else {std::cout << "未設置排序策略" << std::endl;}}private:std::unordered_map<std::string, std::unique_ptr<SortStrategy>> strategies;SortStrategy* currentStrategy;
};// 靜態注冊策略
static StrategyRegistrar<BubbleSort> bubbleRegistrar("bubble");
static StrategyRegistrar<QuickSort> quickRegistrar("quick");// 客戶端代碼
int main() {std::vector<int> data = {5, 4, 3, 2, 1};Sorter sorter;// 使用冒泡排序sorter.setStrategy("bubble");sorter.performSort(data);for (int num : data) {std::cout << num << " ";}std::cout << std::endl;// 切換為快速排序data = {5, 4, 3, 2, 1};sorter.setStrategy("quick");sorter.performSort(data);for (int num : data) {std::cout << num << " ";}std::cout << std::endl;return 0;
}

添加新策略時,只需:

  1. 創建新的策略類,繼承自 SortStrategy
  2. 實現 sort 方法
  3. 添加靜態注冊語句:
    static StrategyRegistrar<NewSortStrategy> newRegistrar("new");
    

// 無需修改 Sorter 類,完全符合開閉原則。
客戶端通過字符串名稱即可使用新策略,實現了對修改封閉,對擴展開放的設計目標。

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

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

相關文章

微信小程序開發-桌面端和移動端UI表現不一致問題記錄

桌面端和移動端UI表現不一致零、引擎說明一、樣式不同1、text 單行&#xff1a;1.1 空格開發者工具不展示&#xff0c;手機/PC端正常1.2 正常展示省略號&#xff0c;需要2、點擊按鈕z-index: -1。webview - 桌面端不行&#xff0c; skyline - 移動端可以&#xff1b;3、其他說明…

極限狀態下函數開根號的計算理解(含示意圖)

遇到一個挺有意思的題做個記錄&#xff1a; 求曲線y (x21)(x2?1)0.5\frac{\left(x^{2}1\right)}{\left(x^{2}-1\right)^{0.5}}(x2?1)0.5(x21)?漸近線的條數 比較明顯的x 1是無定義點。但是在求極限的時候發現1和1-得到的極限值似乎不一樣。似乎是1是趨向于∞&#xff0c;1…

C++——模版(函數模版和類模版)

C 模板&#xff08;Templates&#xff09;完整介紹模板是 C 中一種強大的泛型編程機制&#xff0c;允許開發者編寫與類型無關的代碼&#xff0c;從而提高代碼的復用性和靈活性。通過模板&#xff0c;可以避免為不同數據類型重復編寫相似的函數或類&#xff0c;實現真正的代碼復…

Python之cv2:cv2(OpenCV,opencv-python)庫pip下載超時、下載失敗、無法下載的解決方案大全

Python之cv2&#xff1a;cv2(OpenCV&#xff0c;opencv-python)庫pip下載超時、下載失敗、無法下載的解決方案大全 在學習和使用 OpenCV&#xff08;Python 包名&#xff1a;opencv-python 或簡稱 cv2&#xff09;的過程中&#xff0c;很多初學者常常會遇到通過 pip install o…

asyncio 與 uvloop

事件循環 事件循環 協調所有協程執行的中央調度器&#xff0c;它通過非阻塞機制&#xff0c;實現并發執行多個異步任務。 事件循環是 異步編程的核心機制&#xff0c;用一句話概括就是&#xff1a; 事件循環不斷檢查任務隊列&#xff0c;一旦某個異步任務完成&#xff0c;它…

一文讀懂循環神經網絡(RNN)—語言模型+n元語法(1)

目錄 什么是語言模型&#xff1f; 語言模型的核心目的 一.量化文本的合理性 二.支持下游 NLP 任務 三. 語義和上下文依賴 一元語法、二元語法和三元語法詳解 核心概念&#xff1a;n-gram 模型 1. 一元語法&#xff08;Unigram&#xff09; 2. 二元語法&#xff08;Bigram…

DirectX12(D3D12)基礎教程九 間接繪制

在學習directx12 microsoft提供了很多示例&#xff0c;有簡單的也有復雜,下載網址&#xff1a;https://github.com/microsoft/DirectX-Graphics-Samples 本章對D3D12ExecuteIndirect 示例做了簡化&#xff0c;只保留間接繪制部分&#xff0c;刪除了計算著色器部分。 間接繪制…

fastApi連接數據庫

1&#xff1a;pip install tortoise-orm2&#xff1a;pip install aiomysql3&#xff1a;pip install asyncmy或者使用國內清華園pip install -i https://pypi.tuna.tsinghua.edu.cn/simple asyncmy4&#xff1a;pip install aerich通過 python -m 直接運行&#xff08;推薦&a…

Apache-web服務器環境搭建

目錄 實驗要求 思路總結 1.常規配置web服務 2.通過用戶主頁配置web服務 3.通過虛擬目錄配置web服務 4.添加DNS解析服務&#xff0c;訪問虛擬機域名&#xff1a; www.TestWeb.com 實驗要求 (ip 192.168.48.130) 1、常規配置web服務 2、通過用戶主頁配置web服務 3、通過虛…

Altium Designer 25 安裝與配置完整教程

本教程將帶您一步步完成 Altium Designer 25 的下載、安裝與激活配置 第一步&#xff1a;下載安裝包 首先&#xff0c;需要獲取 Altium Designer 25 的完整安裝程序。 &#x1f449; 下載鏈接&#xff1a; 百度網盤&#xff1a;百度網盤 請輸入提取碼 提取碼: dxei 夸克網盤…

【工具】AndroidStudio修改中文語言漢化

AndroidStudio修改中文語言漢化 https://github.com/sollyu/AndroidStudioChineseLanguagePackhttps://github.com/sollyu/AndroidStudioChineseLanguagePack

代碼隨想錄|圖論|15并查集理論基礎

并查集理論基礎 | 代碼隨想錄 并查集還是比較簡單的&#xff0c;只要搞清楚兩個事情&#xff1a; 并查集是干啥的&#xff1f;解決什么類型問題&#xff1f;并查集模板&#xff08;背下來&#xff09; 1、并查集是干啥的 并查集主要是兩個功能&#xff1a; 兩個元素添加到…

用MYSQL學習sql第一次總結和作業

總結 數據庫&#xff08;Database&#xff09; 理解為“文件夾”&#xff0c;里面可以裝很多張表。作業中要求先建一個名字叫 mydb6_product 的數據庫。 表&#xff08;Table&#xff09; 理解為“Excel 工作表”&#xff0c;由“列&#xff08;字段&#xff09;”和“行&…

SQLite技術架構解析,適用場景有哪些?

一、SQLite技術架構解析 SQLite是一款輕量級、無服務器、嵌入式關系型數據庫&#xff0c;其架構設計圍繞“簡化復雜性、提升效率”展開&#xff0c;核心由前端&#xff08;SQL處理&#xff09;、執行引擎&#xff08;VDBE&#xff09;、存儲引擎&#xff08;B-Tree&#xff09;…

【Luogu】每日一題——Day3. P6392 中意 (數學 取模)

鏈接&#xff1a;P6392 中意 - 洛谷 題目&#xff1a; 思路&#xff1a; 數論這一塊 題目讓我們求這個結果對 MOD 取模&#xff0c;那么我們肯定是不像看到這個除法&#xff0c;所以考慮如何消除這個除法 我們可以想到&#xff0c;向上取整就是加上一個數&#xff0c;假設其為…

React強大且靈活hooks庫——ahooks入門實踐之DOM類hook(dom)詳解

什么是 ahooks&#xff1f; ahooks 是一個 React Hooks 庫&#xff0c;提供了大量實用的自定義 hooks&#xff0c;幫助開發者更高效地構建 React 應用。其中 DOM 類 hooks 是 ahooks 的一個重要分類&#xff0c;專門用于處理 DOM 相關操作&#xff0c;如事件監聽、元素狀態、拖…

GeoTools 工廠設計模式

前言使用GeoTools開發時有必要了解其工廠設計模式&#xff0c;作為軟件開發核心設計模式&#xff0c;其設計思想具有普遍性和研究性。明白方法原理有助于提高開發效率&#xff0c;達到事半功倍的效果。1. 工廠模式 工廠模式&#xff08;Factory Pattern&#xff09;是面向對象中…

npu-smi info命令參數解釋

華為昇騰npu-smi顯示npu-smi工具的幫助信息npu-smi -h字段說明-h命令的幫助信息–help命令的幫助信息-vnpu-smi版本信息info顯示硬件詳細信息set修改設備配置屬性clear清除設備信息upgrade升級MCU固件 npu-smi info 用于監控和管理華為NPU的狀態和性能字段值說明npu-smi24.1.rc…

OneCode3.0 通信架構簡介——MCPServer微內核設計哲學與實現

在數字化轉型加速的今天&#xff0c;低代碼平臺已成為企業快速交付應用的核心基礎設施。然而&#xff0c;通用消息中間件與低代碼開發范式之間存在難以調和的矛盾&#xff1a;標準化協議無法匹配可視化編排的動態性&#xff0c;通用架構難以滿足低代碼場景下高頻短消息的性能需…

Android14 Launcher3 修改All App上下滑動頭部顯示陰影

正常情況下的樣子&#xff1a; 下拉App抽屜后的樣子&#xff1a;修改方案&#xff1a;qssi14/packages/apps/Launcher3/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.javaprotected void updateHeaderScroll(int scrolledOffset) {float prog1 Utilities…