C++策略模式
·
策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列算法,将每个算法封装起来,并使它们可以相互替换。这种模式让算法的变化独立于使用算法的客户端,从而提高代码的灵活性和可维护性。
策略模式的核心角色
- 抽象策略(Strategy):定义所有支持的算法的公共接口
- 具体策略(Concrete Strategy):实现抽象策略接口,提供具体的算法实现
- 上下文(Context):持有一个策略对象的引用,负责使用策略对象,隔离客户端与策略的直接交互
策略模式的实现示例
下面以"支付系统"为例展示策略模式的实现,系统支持多种支付方式(如支付宝、微信支付、信用卡支付),这些支付方式可以相互替换:
#include <iostream>
#include <string>
#include <memory>
// 抽象策略:支付方式
class PaymentStrategy {
public:
virtual void pay(double amount) const = 0;
virtual ~PaymentStrategy() = default;
};
// 具体策略:支付宝支付
class AlipayStrategy : public PaymentStrategy {
private:
std::string account;
public:
AlipayStrategy(const std::string& acc) : account(acc) {}
void pay(double amount) const override {
std::cout << "使用支付宝账户 " << account
<< " 支付了 " << amount << " 元" << std::endl;
}
};
// 具体策略:微信支付
class WechatPayStrategy : public PaymentStrategy {
private:
std::string openId;
public:
WechatPayStrategy(const std::string& id) : openId(id) {}
void pay(double amount) const override {
std::cout << "使用微信账号 " << openId
<< " 支付了 " << amount << " 元" << std::endl;
}
};
// 具体策略:信用卡支付
class CreditCardStrategy : public PaymentStrategy {
private:
std::string cardNumber;
std::string name;
std::string cvv;
std::string expiryDate;
public:
CreditCardStrategy(const std::string& num, const std::string& n,
const std::string& c, const std::string& exp)
: cardNumber(num), name(n), cvv(c), expiryDate(exp) {}
void pay(double amount) const override {
std::cout << "使用信用卡 " << cardNumber << " (" << name
<< ") 支付了 " << amount << " 元" << std::endl;
}
};
// 上下文:购物车
class ShoppingCart {
private:
std::unique_ptr<PaymentStrategy> paymentStrategy;
public:
// 设置支付策略
void setPaymentStrategy(std::unique_ptr<PaymentStrategy> strategy) {
paymentStrategy = std::move(strategy);
}
// 结算
void checkout(double amount) const {
if (paymentStrategy) {
paymentStrategy->pay(amount);
} else {
std::cout << "请选择支付方式" << std::endl;
}
}
};
// 客户端使用
int main() {
ShoppingCart cart;
double totalAmount = 299.99;
// 使用支付宝支付
std::cout << "=== 选择支付宝支付 ===" << std::endl;
cart.setPaymentStrategy(std::make_unique<AlipayStrategy>("user123@alipay.com"));
cart.checkout(totalAmount);
// 切换为微信支付
std::cout << "\n=== 选择微信支付 ===" << std::endl;
cart.setPaymentStrategy(std::make_unique<WechatPayStrategy>("wx123456789"));
cart.checkout(totalAmount);
// 切换为信用卡支付
std::cout << "\n=== 选择信用卡支付 ===" << std::endl;
cart.setPaymentStrategy(std::make_unique<CreditCardStrategy>(
"6222-1234-5678-9012", "张三", "123", "12/25"));
cart.checkout(totalAmount);
return 0;
}
策略模式的工作原理
- 抽象策略定义了所有算法的通用接口,确保所有具体策略具有一致的方法
- 每个具体策略实现了抽象策略的接口,提供不同的算法实现
- 上下文类持有一个策略对象,通过调用策略对象的方法来完成具体操作
- 客户端可以动态地为上下文设置不同的策略对象,从而改变上下文的行为
策略模式与状态模式的区别
- 策略模式:算法是相互独立的,客户端显式选择并切换策略
- 状态模式:状态的切换通常由状态本身或上下文根据条件自动触发,客户端无需知晓
策略模式的应用场景
- 当一个系统需要多种算法,且这些算法需要经常切换时
- 当一个类定义了多种行为,且这些行为在代码中以多个条件语句的形式出现时(可以用策略模式替代条件语句)
- 当需要隐藏算法的实现细节,只暴露其接口时
- 当希望客户端可以选择不同算法,而无需了解算法具体实现时
策略模式的优缺点
优点:
- 实现了算法的封装和复用,使算法可以独立于客户端变化
- 避免了使用多重条件语句,提高了代码的可读性和可维护性
- 符合开放-封闭原则,新增策略只需添加新的具体策略类,无需修改原有代码
- 客户端可以动态切换算法,提高了系统的灵活性
缺点:
- 客户端必须了解所有策略,才能选择合适的策略
- 策略类数量可能过多,增加了系统的复杂度
- 策略之间不能直接通信,如需共享数据需要引入额外机制
策略模式在C++标准库中也有应用,例如std::sort函数可以接受自定义的比较器(策略),从而改变排序行为;STL中的各种容器适配器也体现了策略模式的思想。在实际开发中,策略模式是处理多变算法的有效工具。
更多推荐


所有评论(0)