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

发布于:2025-04-13 ⋅ 阅读:(48) ⋅ 点赞:(0)

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

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

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

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

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

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



在这里插入图片描述

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

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

策略模式特别适合处理:

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

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


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

✅ 需求背景举例:

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

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

if (type == "alipay") {
    ...
} else if (type == "wechat") {
    ...
}

✅ 缺点:

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

这时就需要策略模式!


二、结构定义与核心要点

✅ UML 类图结构

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

✅ 角色说明

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

三、完整 C++ 实现

✅ 抽象策略接口

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

✅ 具体策略类

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;
    }
};

✅ 上下文类

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;
    }
};

✅ 使用示例

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)实战详解:解耦请求者与执行者,构建可撤销、可重做、可排队的操作系统。