设计模式 Day 8:策略模式(Strategy Pattern)完整讲解与实战应用


🔄 前情回顾:Day 7 重点回顾

在 Day 7 中,我们彻底讲透了观察者模式:

它是典型的行为型模式,核心理念是"一变多知",当一个对象状态变化时,自动通知所有订阅者。

我们通过 RxCpp 实现了工业级的事件广播系统,实现了多个模块订阅同一个数据源。

实战中,如协议解包系统、GUI 事件响应、股票系统等,都广泛采用观察者机制。

🔁 观察者模式强调"自动推送消息",而今天我们进入策略模式,它更强调"主动选择行为"!



策略模式(Strategy Pattern)是行为型设计模式中最具"切换能力"的一个,它的设计哲学非常明确:

将算法(行为)抽象为可替换的策略,使得行为的改变不依赖于使用它的对象本身。

策略模式特别适合处理:

  • 多种业务逻辑切换(如支付方式)
  • 动态选择不同算法(如压缩、路径规划)
  • 可扩展、可配置的"策略中心"

本篇 Day 8,将从"动机、结构、语法、实战场景、项目代码、面试回答"六大维度,构建你对策略模式的完整掌握。


一、设计动机:为什么要用策略模式?

✅ 需求背景举例:

  • 一个支付接口,支持支付宝、微信、银行卡......你会怎么设计?
  • 一个路径规划功能,支持最短路、最便宜路径、最快路径......如何实现动态切换?

如果使用 if-else 分支写法:

cpp 复制代码
if (type == "alipay") {
    ...
} else if (type == "wechat") {
    ...
}

✅ 缺点:

  • 不符合开闭原则
  • 不方便扩展新策略
  • 无法复用策略逻辑

这时就需要策略模式!


二、结构定义与核心要点

✅ UML 类图结构

复制代码
+------------------+
|   Strategy       |<------------------------------+
+------------------+                               |
| + execute()      |                               |
+------------------+                               |
        /\                                          |
        ||                                          |
+-------------------+     +-----------------------+ |
| AlipayStrategy     |     | WeChatStrategy        | |
+-------------------+     +-----------------------+ |
| + execute()        |     | + execute()           | |
+-------------------+     +-----------------------+ |
                                                   |
              +------------------------------+     |
              |     PaymentContext           |-----+
              +------------------------------+
              | - strategy: Strategy*        |
              | + setStrategy(Strategy*)     |
              | + pay()                      |
              +------------------------------+

✅ 角色说明

角色 职责
Strategy 策略接口,声明统一算法方法
ConcreteStrategy 具体策略类,封装各自逻辑
Context 上下文,持有当前策略对象

三、完整 C++ 实现

✅ 抽象策略接口

cpp 复制代码
class PaymentStrategy {
public:
    virtual void pay(int amount) = 0;
    virtual ~PaymentStrategy() = default;
};

✅ 具体策略类

cpp 复制代码
class AlipayStrategy : public PaymentStrategy {
public:
    void pay(int amount) override {
        std::cout << "使用支付宝支付: " << amount << " 元" << std::endl;
    }
};

class WeChatStrategy : public PaymentStrategy {
public:
    void pay(int amount) override {
        std::cout << "使用微信支付: " << amount << " 元" << std::endl;
    }
};

class CreditCardStrategy : public PaymentStrategy {
public:
    void pay(int amount) override {
        std::cout << "使用信用卡支付: " << amount << " 元" << std::endl;
    }
};

✅ 上下文类

cpp 复制代码
class PaymentContext {
private:
    std::unique_ptr<PaymentStrategy> strategy_;

public:
    void setStrategy(std::unique_ptr<PaymentStrategy> strategy) {
        strategy_ = std::move(strategy);
    }

    void pay(int amount) {
        if (strategy_)
            strategy_->pay(amount);
        else
            std::cout << "未设置支付方式!" << std::endl;
    }
};

✅ 使用示例

cpp 复制代码
int main() {
    PaymentContext context;

    context.setStrategy(std::make_unique<AlipayStrategy>());
    context.pay(100);

    context.setStrategy(std::make_unique<WeChatStrategy>());
    context.pay(200);

    context.setStrategy(std::make_unique<CreditCardStrategy>());
    context.pay(300);
    return 0;
}

四、真实项目中策略模式的应用场景

应用领域 策略角色示例
支付系统 支付方式切换:微信、支付宝、银行卡
压缩服务 gzip、zip、lz4 等算法策略
游戏角色AI 攻击策略、防御策略、逃跑策略
电商促销系统 折扣策略、满减策略、积分兑换策略
导航/路径规划 最快路线、最短路线、避开拥堵路线
编解码框架 JSON、XML、YAML 策略
图像处理 多种滤镜、降噪算法策略

五、与状态模式、策略模式、工厂模式的对比

对比项 策略模式 状态模式 工厂模式
意图 封装行为算法,动态切换 封装对象状态与行为 封装创建过程,替代 new
变化点 行为逻辑 状态 + 行为 对象类型
是否持有引用 Context 中持有策略对象 状态机中持有当前状态对象 工厂方法中返回具体对象

六、面试表达模板 + 问答技巧

❓面试官:你用过策略模式吗?什么场景?

✅ 回答示例:

"在我们支付平台中使用了策略模式来解耦支付方式。我们定义了 PaymentStrategy 接口,具体实现了 AlipayStrategyWeChatStrategy 等类,业务调用通过 PaymentContext 设置策略并执行。策略模式让新增支付方式变得非常方便,无需改动旧逻辑,只需新增类即可。"

✅ 加分点:

  • 强调"符合开闭原则"
  • 使用 std::unique_ptr 管理生命周期
  • 提出策略配置可从配置文件加载(JSON -> 类)

七、总结回顾 + 记忆口诀

✅ 策略模式关键词:

  • 行为可切换
  • 算法封装
  • 运行时替换
  • 开闭原则
  • 模块解耦

📌 记忆口诀:

"行为封装进策略,替换逻辑不靠 if,扩展功能加新类,变化收敛更灵活。"


八、明日预告:Day 9

命令模式(Command Pattern)实战详解:解耦请求者与执行者,构建可撤销、可重做、可排队的操作系统。

相关推荐
浅陌sss1 小时前
设计模式 --- 策略模式
设计模式
我只有一岁半3 小时前
策略模式实现 Bean 注入时怎么知道具体注入的是哪个 Bean?
spring·策略模式
FirstMrRight3 小时前
策略模式随笔~
后端·设计模式
NorthCastle4 小时前
设计模式-结构型模式-代理模式
java·设计模式·代理模式
小马爱打代码4 小时前
设计模式:里氏代换原则 - 继承设计的稳定之道
设计模式
快乐源泉6 小时前
【设计模式】桥接,是设计模式?对,其实你用过
后端·设计模式·go
Auroral1566 小时前
创建型模式:抽象工厂模式
设计模式
都叫我大帅哥6 小时前
代码界的「海关检查」:访问者模式的签证艺术
java·后端·设计模式
小马爱打代码6 小时前
设计模式:代理模式 - 控制访问与增强功能的艺术
设计模式·代理模式
wenbin_java6 小时前
设计模式之备忘录模式:对象状态的可逆时光机
java·设计模式·备忘录模式