🔄 前情回顾: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
接口,具体实现了AlipayStrategy
、WeChatStrategy
等类,业务调用通过PaymentContext
设置策略并执行。策略模式让新增支付方式变得非常方便,无需改动旧逻辑,只需新增类即可。"
✅ 加分点:
- 强调"符合开闭原则"
- 使用
std::unique_ptr
管理生命周期 - 提出策略配置可从配置文件加载(JSON -> 类)
七、总结回顾 + 记忆口诀
✅ 策略模式关键词:
- 行为可切换
- 算法封装
- 运行时替换
- 开闭原则
- 模块解耦
📌 记忆口诀:
"行为封装进策略,替换逻辑不靠 if,扩展功能加新类,变化收敛更灵活。"
八、明日预告:Day 9
命令模式(Command Pattern)实战详解:解耦请求者与执行者,构建可撤销、可重做、可排队的操作系统。