Bootstrap

「软件设计模式」策略模式(Strategy)

软件设计模式深度解析:策略模式(Strategy Pattern)的精髓与实践

一、设计模式思想:以柔克刚的算法封装术

在软件开发中,我们经常会遇到需要动态切换算法或策略的场景。传统的硬编码方式会导致代码臃肿、维护困难,而策略模式(Strategy Pattern)正是解决这类问题的利器。该模式通过将算法族进行抽象封装,使其能够独立于客户端变化,完美体现了开闭原则(OCP)组合优于继承的设计思想。

策略模式三大核心角色:

  1. Context(环境类):维护策略引用的执行环境
  2. Strategy(抽象策略):定义算法族的统一接口
  3. ConcreteStrategy(具体策略):实现具体的算法行为

二、实战演练:电商支付系统的策略演进

传统实现方式的困境

// 硬编码的支付方式选择
void processPayment(double amount, string paymentType) {
    if (paymentType == "Alipay") {
        // 支付宝支付逻辑
    } else if (paymentType == "WeChatPay") {
        // 微信支付逻辑
    } else if (paymentType == "CreditCard") {
        // 信用卡支付逻辑
    }
    // 新增支付方式需要修改此处
}

策略模式解决方案

步骤1:定义策略接口

class PaymentStrategy {
public:
    virtual ~PaymentStrategy() = default;
    virtual void pay(double amount) const = 0;
};

步骤2:实现具体策略

class AlipayStrategy : public PaymentStrategy {
public:
    void pay(double amount) const override {
        cout << "支付宝支付:" << amount << "元" << endl;
        // 调用支付宝SDK
    }
};

class WeChatPayStrategy : public PaymentStrategy {
public:
    void pay(double amount) const override {
        cout << "微信支付:" << amount << "元" << endl;
        // 调用微信支付接口
    }
};

步骤3:构建策略上下文

class PaymentContext {
private:
    unique_ptr<PaymentStrategy> strategy;
    
public:
    explicit PaymentContext(unique_ptr<PaymentStrategy> &&strategy)
        : strategy(move(strategy)) {}

    void executePayment(double amount) const {
        if (strategy) {
            strategy->pay(amount);
        }
    }

    void setStrategy(unique_ptr<PaymentStrategy> &&newStrategy) {
        strategy = move(newStrategy);
    }
};

步骤4:客户端灵活调用

int main() {
    // 创建支付上下文
    PaymentContext context(make_unique<AlipayStrategy>());
    
    // 执行默认策略
    context.executePayment(100.0);  // 支付宝支付100元
    
    // 动态切换策略
    context.setStrategy(make_unique<WeChatPayStrategy>());
    context.executePayment(200.0);  // 微信支付200元
    
    return 0;
}

 步骤5:运行结果

支付宝支付:100元
微信支付:200元

三、策略模式进阶应用技巧

1. 策略工厂模式结合

class PaymentStrategyFactory {
public:
    static unique_ptr<PaymentStrategy> createStrategy(const string &type) {
        if (type == "Alipay") 
            return make_unique<AlipayStrategy>();
        if (type == "WeChatPay")
            return make_unique<WeChatPayStrategy>();
        throw invalid_argument("Unsupported payment type");
    }
};

 调用方法:

#include <iostream>
#include "advanced_pay.h"

int main(int argc, char const *argv[]) {
    // 客户端调用
    auto alipayLambda = [](double amt) {
        cout << "Lambda支付宝支付:" << amt << endl;
    };

    auto weChatLambda = [](double amt) {
        cout << "Lambda微信支付:" << amt << endl;
    };
    GenericPaymentContext<decltype(alipayLambda)> ctx(alipayLambda);
    ctx.executePayment(150.0);

    GenericPaymentContext<decltype(weChatLambda)> ctx2(weChatLambda);
    ctx2.executePayment(200.0);
    return 0;
}

  运行结果:

Lambda支付宝支付:150
Lambda微信支付:200

2. 策略参数配置化

// 通过JSON配置动态加载策略
{
    "payment_config": {
        "default_strategy": "Alipay",
        "strategies": {
            "Alipay": {
                "merchant_id": "2088xxxx",
                "notify_url": "/api/pay/notify"
            },
            "WeChatPay": {
                "app_id": "wx88888888",
                "mch_id": "1230000109"
            }
        }
    }
}

四、策略模式优劣辩证观

优势亮点:

  1. 消除条件判断:通过多态代替if-else分支
  2. 扩展性强:新增策略无需修改既有代码
  3. 算法复用:策略可在不同环境中共享
  4. 运行时切换:动态改变对象行为

适用场景:

  • 系统需要多种算法变体
  • 存在多重条件判断的相似算法
  • 需要隔离算法实现与使用逻辑
  • 算法需要自由切换或组合使用

潜在缺陷:

  • 策略类数量可能爆炸式增长
  • 客户端需要了解策略差异
  • 增加对象间通信开销

五、工程实践中的策略模式变体

1. Lambda策略(C++14+)

2. 策略自动注册机制

六、从策略模式看设计原则

  1. 开闭原则(OCP):对扩展开放,对修改关闭
  2. 单一职责原则(SRP):每个策略只负责一个算法
  3. 依赖倒置原则(DIP):高层模块依赖抽象接口
  4. 组合复用原则(CARP):通过对象组合实现复用

七、总结与展望

        策略模式作为行为型设计模式的代表,为算法管理提供了优雅的解决方案。在现代C++开发中,结合模板、lambda表达式等新特性,策略模式展现出更强大的生命力。随着领域驱动设计(DDD)的普及,策略模式在战术模式实现中也发挥着重要作用。

;