C++ 设计模式-策略模式

news/2025/2/22 11:01:41

支付策略

#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); // 自动转换为BTC

    return 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.niftyadmin.cn/n/5862148.html

相关文章

Linux驱动开发之音频驱动与基础应用编程

目录 CODEC芯片 音频编码 I2S总线接口 数字音频接口(DAI) 设备树配置 ALSA 音频相关概念 应用程序编写 运行测试 CODEC芯片 音频若想被CPU“听到”&#xff0c;就必须转换为CPU能够“听懂”的语言&#xff0c;即二进制数据的0和1。在信号处理领域&#xff0c;声音是模…

pandas数据存到informix数据库

紧接上文python 连接infomix&#xff0c;结合pandas&#xff0c;补充csdn在这方面的经验 。 由于无法通过sqlalchemy连接数据库ibm的informix数据库。得用jaydebeapi的jar包。 那么这篇文章就是介绍如何将十几万条的pandas的数据存到informix中。 ok&#xff0c;首先我们读取…

【从0做项目】Java音缘心动(1)———项目介绍设计

阿华代码&#xff0c;不是逆风&#xff0c;就是我疯 你们的点赞收藏是我前进最大的动力&#xff01;&#xff01; 希望本文内容能够帮助到你&#xff01;&#xff01; 目录 零&#xff1a;项目结果展示 一&#xff1a;音乐播放器Web网页介绍 二&#xff1a;前期准备工作&…

Effective Objective-C 2.0 读书笔记——协议和分类

Effective Objective-C 2.0 读书笔记——协议和分类 文章目录 Effective Objective-C 2.0 读书笔记——协议和分类在分类中添加属性使用 “class-continuation分类” 隐藏实现细节通过协议提供匿名对象 在分类中添加属性 尽管从技术上说&#xff0c;分类里也可以声明属性&…

JAVA JUC 并发编程学习笔记(一)

文章目录 JUC进程概述对比 线程创建线程ThreadRunnableCallable 线程方法APIrun startsleep yieldjoininterrupt打断线程打断 park终止模式 daemon不推荐 线程原理运行机制线程调度未来优化 线程状态查看线程 同步临界区syn-ed使用锁同步块同步方法线程八锁 锁原理Monitor字节码…

如何用deepseek快速生成思维导图和流程图?

一起来看看md格式和mermaid格式&#xff0c;与deepseek的碰撞会产生怎样的魔法吧&#xff01; 1、md格式deepseek&#xff0c;快速生成思维导图 Markdown 是一种轻量级的标记语言&#xff0c;旨在以易读易写的纯文本格式编写文档&#xff0c;并能够轻松转换为结构化的 HTML&a…

Spring Boot (maven)分页4.0.1版本 专业版- 改

前言&#xff1a; 通过实践而发现真理&#xff0c;又通过实践而证实真理和发展真理。从感性认识而能动地发展到理性认识&#xff0c;又从理性认识而能动地指导革命实践&#xff0c;改造主观世界和客观世界。实践、认识、再实践、再认识&#xff0c;这种形式&#xff0c;循环往…

C++17中的std::scoped_lock:简化多锁管理的利器

文章目录 1. 为什么需要std::scoped_lock1.1 死锁问题1.2 异常安全性1.3 锁的管理复杂性 2. std::scoped_lock的使用方法2.1 基本语法2.2 支持多种互斥锁类型2.3 自动处理异常 3. std::scoped_lock的优势3.1 避免死锁3.2 简化代码3.3 提供异常安全保证 4. 实际应用场景4.1 数据…