策略模式(Strategy Pattern)
一、什么是策略模式
策略模式是一种行为型设计模式,它定义了一系列算法(策略),并将每个算法封装起来,使它们可以互相替换。
策略模式让算法的变化独立于使用算法的客户端。
二、解决了什么问题
- 当系统中有多种算法(或行为)可以替换时,如果写在
if-else或switch语句中,会导致代码臃肿、难以维护。 (不是所有的 if 都应该被替换为策略模式。对于逻辑简单、变化不大的分支,使用 if-else 反而更直观;只有在分支逻辑复杂、需要灵活扩展或动态切换行为时,策略模式才能体现出优势。) - 策略模式通过面向接口编程,将不同的算法封装为独立类,使得它们能灵活切换。
三、模式的核心思想
- 定义一个抽象策略接口,声明算法的共同方法。
- 每个具体策略类实现该接口,封装具体算法。
- 上下文类(Context)持有一个策略对象,并在需要时调用该策略的方法。
四、结构图
抽象策略 Strategy
└── 算法方法 algorithm()
具体策略 ConcreteStrategyA
└── 实现 algorithm()
具体策略 ConcreteStrategyB
└── 实现 algorithm()
上下文 Context
└── 持有 Strategy 引用,调用其方法
五、代码样例
- 场景:我们日常购物时,支付方式可能是 支付宝 / 微信 / 银行卡。
不使用策略模式(写死if-else)
#include <iostream>
#include <string>
using namespace std;
class Payment {
public:
void pay(string type) {
if (type == "Alipay") {
cout << "使用支付宝支付\n";
} else if (type == "WeChat") {
cout << "使用微信支付\n";
} else if (type == "Bank") {
cout << "使用银行卡支付\n";
} else {
cout << "未知支付方式\n";
}
}
};
int main() {
Payment p;
p.pay("Alipay");
p.pay("WeChat");
return 0;
}
使用策略模式
抽象策略接口
class PayStrategy {
public:
virtual ~PayStrategy() {}
virtual void pay() = 0;
};
以下为具体策略
class Alipay : public PayStrategy {
public:
void pay() override {
cout << "使用支付宝支付\n";
}
};
class WeChatPay : public PayStrategy {
public:
void pay() override {
cout << "使用微信支付\n";
}
};
class BankPay : public PayStrategy {
public:
void pay() override {
cout << "使用银行卡支付\n";
}
};
上下文类(持有策略)
class PaymentContext {
private:
PayStrategy* strategy;
public:
PaymentContext(PayStrategy* s) : strategy(s) {}
void setStrategy(PayStrategy* s) { strategy = s; }
void pay() { strategy->pay(); }
};
使用示例
int main() {
PayStrategy* alipay = new Alipay();
PayStrategy* wechat = new WeChatPay();
PayStrategy* bank = new BankPay();
PaymentContext context(alipay);
cout << "第一次支付:\n";
context.pay();
cout << "\n切换为微信支付:\n";
context.setStrategy(wechat);
context.pay();
cout << "\n切换为银行卡支付:\n";
context.setStrategy(bank);
context.pay();
delete alipay;
delete wechat;
delete bank;
return 0;
}
六、优缺点
优点:
-
算法封装独立,遵循开闭原则,易于扩展。
-
消除了多重 if-else,提高代码清晰度。
-
策略可以在运行时自由切换。
缺点:
-
客户端必须知道有哪些策略,并且主动选择合适的策略。
-
如果策略类过多,可能增加系统复杂性。
七、应用场景
当系统中需要在运行时切换不同算法或行为。
例如:
排序(快速排序、归并排序等)。
支付方式(支付宝、微信、银行卡)。
日志输出策略(控制台、文件、网络)。
稳定与变化
- 稳定:PaymentContext 持有 PayStrategy,并调用 pay() 方法。
- 变化:具体支付方式(支付宝 / 微信 / 银行卡)。
1174

被折叠的 条评论
为什么被折叠?



