C++ 設計模式-策略模式

支付策略

#include <iostream>
#include <memory>
#include <unordered_map>
#include <vector>
#include <ctime>// 基礎策略接口
class PaymentStrategy {
public:virtual ~PaymentStrategy() = default;virtual std::string name() const = 0;virtual bool validate(double amount, const std::string& currency) const = 0;virtual void pay(double amount, const std::string& currency) const = 0;virtual double calculate_fee(double amount) const = 0;
};// 策略工廠系統
class StrategyFactory {
public:using StrategyCreator = std::function<std::unique_ptr<PaymentStrategy>()>;static StrategyFactory& instance() {static StrategyFactory instance;return instance;}void register_strategy(const std::string& id, StrategyCreator creator) {creators_[id] = creator;}std::unique_ptr<PaymentStrategy> create(const std::string& id) const {if (auto it = creators_.find(id); it != creators_.end()) {return it->second();}return nullptr;}std::vector<std::string> available_strategies() const {std::vector<std::string> names;for (const auto& [id, _] : creators_) {names.push_back(id);}return names;}private:std::unordered_map<std::string, StrategyCreator> creators_;
};// 自動注冊宏
#define REGISTER_PAYMENT_STRATEGY(StrategyClass, strategy_id) \namespace { \struct AutoRegister_##StrategyClass { \AutoRegister_##StrategyClass() { \StrategyFactory::instance().register_strategy( \strategy_id, \[]{ return std::make_unique<StrategyClass>(); } \); \} \}; \AutoRegister_##StrategyClass auto_reg_##StrategyClass; \}// 微信支付策略
class WechatPayStrategy : public PaymentStrategy {const double max_amount_ = 50000.0; // 單筆最大金額public:std::string name() const override { return "WeChat Pay"; }bool validate(double amount, const std::string& currency) const override {return currency == "CNY" && amount <= max_amount_;}void pay(double amount, const std::string& currency) const override {std::cout << "微信支付成功\n"<< "金額: ¥" << amount << "\n"<< "請在小程序確認支付" << std::endl;}double calculate_fee(double amount) const override {return amount * 0.001; // 0.1%手續費}
};
REGISTER_PAYMENT_STRATEGY(WechatPayStrategy, "wechat_pay");// PayPal策略
class PayPalStrategy : public PaymentStrategy {const std::vector<std::string> supported_currencies_{"USD", "EUR", "GBP"};public:std::string name() const override { return "PayPal"; }bool validate(double amount, const std::string& currency) const override {return std::find(supported_currencies_.begin(), supported_currencies_.end(), currency) != supported_currencies_.end();}void pay(double amount, const std::string& currency) const override {std::cout << "Processing PayPal payment\n"<< "Amount: " << currency << " " << amount << "\n"<< "Redirecting to PayPal login..." << std::endl;}double calculate_fee(double amount) const override {return std::max(0.3, amount * 0.05); // 5% + $0.3}
};
REGISTER_PAYMENT_STRATEGY(PayPalStrategy, "paypal");// 比特幣策略(帶實時匯率)
class BitcoinStrategy : public PaymentStrategy {// 模擬實時匯率獲取double get_bitcoin_price() const {static const double BASE_PRICE = 45000.0; // 基礎價格// 模擬價格波動return BASE_PRICE * (1.0 + 0.1 * sin(time(nullptr) % 3600));}public:std::string name() const override { return "Bitcoin"; }bool validate(double amount, const std::string& currency) const override {return currency == "BTC" || currency == "USD";}void pay(double amount, const std::string& currency) const override {if (currency == "USD") {double btc_amount = amount / get_bitcoin_price();std::cout << "Converting USD to BTC: " << "?" << btc_amount << std::endl;amount = btc_amount;}std::cout << "區塊鏈交易確認中...\n"<< "轉賬金額: ?" << amount << "\n"<< "預計確認時間: 10分鐘" << std::endl;}double calculate_fee(double amount) const override {return 0.0001 * get_bitcoin_price(); // 固定礦工費}
};
REGISTER_PAYMENT_STRATEGY(BitcoinStrategy, "bitcoin");// 支付處理器
class PaymentProcessor {std::unordered_map<std::string, std::unique_ptr<PaymentStrategy>> strategies_;public:void load_strategy(const std::string& id) {if (auto strategy = StrategyFactory::instance().create(id)) {strategies_[id] = std::move(strategy);}}void process_payment(const std::string& currency, double amount) {auto strategy = select_strategy(currency, amount);if (!strategy) {throw std::runtime_error("No available payment method");}std::cout << "\n=== 支付方式: " << strategy->name() << " ==="<< "\n金額: " << currency << " " << amount<< "\n手續費: " << strategy->calculate_fee(amount)<< "\n-------------------------" << std::endl;strategy->pay(amount, currency);}private:PaymentStrategy* select_strategy(const std::string& currency, double amount) {// 選擇優先級:本地支付 > 國際支付 > 加密貨幣for (auto& [id, strategy] : strategies_) {if (id == "wechat_pay" && strategy->validate(amount, currency)) {return strategy.get();}}for (auto& [id, strategy] : strategies_) {if (id == "alipay" && strategy->validate(amount, currency)) {return strategy.get();}}for (auto& [id, strategy] : strategies_) {if (strategy->validate(amount, currency)) {return strategy.get();}}return nullptr;}
};// 使用示例
int main() {PaymentProcessor processor;// 加載所有注冊的支付方式for (const auto& id : StrategyFactory::instance().available_strategies()) {processor.load_strategy(id);}// 人民幣支付try {processor.process_payment("CNY", 200.0);processor.process_payment("CNY", 60000.0); // 應觸發異常} catch (const std::exception& e) {std::cerr << "支付失敗: " << e.what() << std::endl;}// 美元支付processor.process_payment("USD", 500.0);// 比特幣支付processor.process_payment("BTC", 0.1);processor.process_payment("USD", 1000.0); // 自動轉換為BTCreturn 0;
}

代碼解析

  1. 策略擴展機制
REGISTER_PAYMENT_STRATEGY(WechatPayStrategy, "wechat_pay");
  • 自動注冊:通過宏實現新策略的零配置接入
  • 唯一標識:每個策略有唯一的注冊ID(如wechat_pay)
  1. 微信支付實現
class WechatPayStrategy : public PaymentStrategy {bool validate(...) { /* 校驗人民幣 */ }void pay(...) { /* 微信特有流程 */ }
};
  • 本地化支持:僅接受人民幣
  • 移動支付流程:模擬小程序支付場景
  1. PayPal國際支付
class PayPalStrategy : public PaymentStrategy {bool validate(...) { /* 支持多幣種 */ }void pay(...) { /* 跳轉PayPal */ }
};
  • 多幣種支持:USD/EUR/GBP
  • 典型手續費模型:固定費用+百分比
  1. 比特幣支付
class BitcoinStrategy : public PaymentStrategy {double get_bitcoin_price() { /* 模擬實時價格 */ }void pay(...) { /* 自動轉換法幣 */ }
};
  • 加密貨幣支持:直接接受BTC或自動轉換USD
  • 動態手續費:基于當前幣價計算礦工費
  1. 智能策略選擇
PaymentStrategy* select_strategy(...) {// 優先選擇本地支付方式// 次選國際支付// 最后考慮加密貨幣
}
  • 業務優先級:體現支付方式選擇策略
  • 動態路由:根據金額和幣種自動路由

執行結果示例

=== 支付方式: WeChat Pay ===
金額: CNY 200
手續費: 0.2
-------------------------
微信支付成功
金額: ¥200
請在小程序確認支付支付失敗: No available payment method=== 支付方式: PayPal ===
金額: USD 500
手續費: 25.3
-------------------------
Processing PayPal payment
Amount: USD 500
Redirecting to PayPal login...=== 支付方式: Bitcoin ===
金額: BTC 0.1
手續費: 4.5
-------------------------
區塊鏈交易確認中...
轉賬金額: ?0.1
預計確認時間: 10分鐘=== 支付方式: Bitcoin ===
金額: USD 1000
手續費: 4.5
-------------------------
Converting USD to BTC: ?0.0221132
區塊鏈交易確認中...
轉賬金額: ?0.0221132
預計確認時間: 10分鐘

待擴展

  1. 新增策略步驟

    • 繼承PaymentStrategy實現新類
    • 實現所有純虛函數
    • 使用REGISTER_PAYMENT_STRATEGY注冊
  2. 動態配置

    // 示例:從JSON加載策略配置
    void load_config(const json& config) {for (auto& item : config["strategies"]) {auto strategy = factory.create(item["id"]);strategy->configure(item["params"]);add_strategy(std::move(strategy));}
    }
    
  3. 混合支付

    class SplitPaymentStrategy : public PaymentStrategy {// 支持多個策略分攤支付void pay(...) override {credit_card_->pay(part1, currency);crypto_->pay(part2, currency);}
    };

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

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

相關文章

國產編輯器EverEdit - 如何在EverEdit中管理工程?

1 工程管理 1.1 應用場景 用戶創建工程后&#xff0c;會涉及到工程的管理 &#xff0c;比如&#xff1a;打開工程、關閉工程等 1.2 使用方法 1.2.1 打開工程 單擊主菜單工程 -> 打開工程&#xff0c;會彈出打開對話框&#xff0c;用戶在對話框中選擇需要打開的工程文件即…

MYSQL-數據庫-DDL-DML-DQL-DCL-基礎學習

MySql概念&#xff1a; 建立在關系模型基礎上&#xff0c;有多張相互連接的二維表組成的數據庫 SQL通用語法&#xff1a; 1.SQL語句可以單行或多行書寫&#xff0c;以分號結尾 2.SQL語句可以使用空格/縮進來增強語句的可讀性 3.MySQL數據庫的SQL語句不區分大小寫&#xff0c;關…

SpringBoot核心框架之AOP詳解

SpringBoot核心框架之AOP詳解 一、AOP基礎 1.1 AOP概述 AOP&#xff1a;Aspect Oriented Programming&#xff08;面向切面編程&#xff0c;面向方面編程&#xff09;&#xff0c;其實就是面向特定方法編程。 場景&#xff1a;項目部分功能運行較慢&#xff0c;定位執行耗時…

【RK3588嵌入式圖形編程】-SDL2-構建模塊化UI

構建模塊化UI 文章目錄 構建模塊化UI1、概述2、創建UI管理器3、嵌套組件4、繼承5、多態子組件6、總結在本文中,將介紹如何使用C++和SDL創建一個靈活且可擴展的UI系統,重點關注組件層次結構和多態性。 1、概述 在前面的文章中,我們介紹了應用程序循環和事件循環,這為我們的…

第四屆圖像、信號處理與模式識別國際學術會議(ISPP 2025)

重要信息 會議官網&#xff1a;www.icispp.com 會議時間&#xff1a;2025年3月28-30日 會議地點&#xff1a;南京 簡介 由河海大學和江蘇大學聯合主辦的第四屆圖像、信號處理與模式識別國際學術會議&#xff08;ISPP 2025) 將于2025年3月28日-30日在中國南京舉行。會議主…

低代碼與開發框架的一些整合[2]

1.分析的項目資源說明 經過近期的的不斷分析與運行對比&#xff0c;最終把注意力集中在了以下幾個框架&#xff1a; 01.dibootdiboot.diboot: 寫的更少, 性能更好 -> 為開發人員打造的低代碼開發平臺。Mybatis-plus關聯查詢&#xff0c;關聯無SQL&#xff0c;性能高10倍&a…

Spring Boot 中事務的用法詳解

引言 在 Spring Boot 中&#xff0c;事務管理是一個非常重要的功能&#xff0c;尤其是在涉及數據庫操作的業務場景中。Spring 提供了強大的事務管理支持&#xff0c;能夠幫助我們簡化事務的管理和控制。本文將詳細介紹 Spring Boot 中事務的用法&#xff0c;包括事務的基本概…

Java面試——Tomcat

優質博文&#xff1a;IT_BLOG_CN 一、Tomcat 頂層架構 Tomcat中最頂層的容器是Server&#xff0c;代表著整個服務器&#xff0c;從上圖中可以看出&#xff0c;一個Server可以包含至少一個Service&#xff0c;用于具體提供服務。Service主要包含兩個部分&#xff1a;Connector和…

第4章 信息系統架構(三)

4.3 應用架構 應用架構的主要內容是規劃出目標應用分層分域架構&#xff0c;根據業務架構規劃目標應用域、應用組和目標應用組件&#xff0c;形成目標應用架構邏輯視圖和系統視圖。從功能視角出發&#xff0c;闡述應用組件各自及應用架構整體上&#xff0c;如何實現組織的高階…

python小項目編程-中級(1、圖像處理)

目錄 圖像處理 實現 測試 unittest pytest 圖像處理 實現界面化操作&#xff0c;使用PIL庫實現簡單的圖像處理功能&#xff0c;如縮放&#xff08;設置縮放比例&#xff09;、旋轉和濾鏡、對比度調整、亮度調整、灰度圖、二值化圖&#xff08;二值圖如果使用的是彩色圖片需…

【Leetcode 每日一題】2209. 用地毯覆蓋后的最少白色磚塊

問題背景 給你一個下標從 0 0 0 開始的 二進制 字符串 f l o o r floor floor&#xff0c;它表示地板上磚塊的顏色。 f l o o r [ i ] floor[i] floor[i] 為 ‘0’ 表示地板上第 i i i 塊磚塊的顏色是 黑色 。 f l o o r [ i ] floor[i] floor[i] 為’1’ 表示地板上第 i …

Docker 性能優化指南

Docker 提供了強大的容器化功能&#xff0c;能夠幫助開發者在不同的環境中構建、測試和部署應用。然而&#xff0c;隨著容器化應用的不斷增長&#xff0c;Docker 容器可能會面臨一些性能瓶頸&#xff0c;影響其運行效率、資源占用和擴展能力。為了確保容器在生產環境中的高效運…

2025 WE DAY品牌日| 天璇II WE X7 Pro充電樁震撼發布,能效電氣開啟充電革命

隨著新能源產業的迅猛發展,充電樁作為電動汽車能量補給的重要基礎設施,正在成為市場關注的焦點。能效電氣作為充電樁領域的佼佼者,專注于研發高效、智能的充電解決方案,為電動汽車的普及與可持續發展鋪設了堅實的基礎。 2025年2月21日,能效電氣在深圳盛大舉辦了以“以創新 引未…

< OS 有關 > Ubuntu 24 SSH 服務器更換端口 in jp/us VPSs

原因&#xff1a; 兩臺 VPS 的 ssh 端口一直被密碼重試&#xff0c; us 這臺已經封了 632, jp 這臺兩周前清過一次 sqlite3 數據&#xff0c;現在贊到 1008 Fail2Ban 是使用 sqlite3 來記錄&#xff0c;數據量大后&#xff0c;硬盤的 I/O 會飆升&#xff0c;我有寫過一個 app…

MATLAB學習之旅:數據插值與曲線擬合

在MATLAB的奇妙世界里,我們已經走過了一段又一段的學習旅程。從基礎的語法和數據處理,到如今,我們即將踏入數據插值與曲線擬合這片充滿魅力的領域。這個領域就像是魔法中的藝術創作,能夠讓我們根據現有的數據點,構建出更加豐富的曲線和曲面,從而更好地理解和描述數據背后…

若依-@Excel新增注解numberFormat

Excel注解中原本的scale會四舍五入小數&#xff0c;導致進度丟失 想要的效果 顯示的時候保留兩個小數真正的數值是保留之前的數值 還原過程 若以中有一個專門的工具類&#xff0c;用來處理excel的 找到EXCEL導出方法exportExcel()找到writeSheet,寫表格的方法找到填充數據的方法…

LeetCode 熱題 100_搜索二維矩陣(64_74_中等_C++)(二分查找)(暴力破解法;Z字形查找;一次二分查找)

LeetCode 熱題 100_搜索二維矩陣&#xff08;64_74&#xff09; 題目描述&#xff1a;輸入輸出樣例&#xff1a;題解&#xff1a;解題思路&#xff1a;思路一&#xff08;暴力破解法&#xff09;&#xff1a;思路二&#xff08;Z字形查找&#xff09;&#xff1a;思路三&#x…

從CNN到Transformer:遙感影像目標檢測的技術演進(礦產勘探、精準農業、城市規劃、林業測量、軍事目標識別和災害評估等)

在遙感影像分析領域&#xff0c;目標檢測一直是研究熱點之一。隨著高分辨率對地觀測系統的不斷發展&#xff0c;遙感影像的分辨率和數據量呈爆發式增長&#xff0c;如何高效、準確地從海量數據中提取有用信息&#xff0c;成為了一個亟待解決的問題。近年來&#xff0c;深度學習…

【rt-thread】rt-thread 控制 led 的兩種方式

1. pin設備 #define LED_PIN 3int led(void) {rt_uint8_t count;rt_pin_mode(LED_PIN, PIN_MODE_OUTPUT); for(count 0 ; count < 10 ;count){ rt_pin_write(LED_PIN, PIN_HIGH);rt_kprintf("led on, count : %d %d\r\n", count, rt_pin_read(LED_PIN));…

Excell 代碼處理

文章目錄 Excell 代碼處理cvc格式xlsl格式小結 Excell 代碼處理 有時候要對excell進行分析&#xff0c;或者數據的導入導出&#xff0c;這個時候如果可以用代碼讀寫分析操作那么會方便很多 cvc格式 CSV&#xff08;Comma-Separated Values&#xff0c;逗號分隔值&#xff09;是…