策略模式_行为型_GOF23
策略模式
策略模式(Strategy Pattern)是一种行为型设计模式,核心思想是将一组算法封装成独立对象,使它们可以相互替换,从而让算法的变化独立于使用它的客户端。这类似于游戏中的技能切换——玩家根据战况选择不同技能(火球术、冰箭术),而角色的攻击逻辑无需修改。
一、通俗理解
以商场促销为例:
- 传统方式:用
if-else
判断促销类型(满减、折扣、积分),导致代码臃肿且难以扩展新促销策略。 - 策略模式:
- 促销策略接口:定义统一的优惠计算接口(如
calculate()
)。 - 具体策略类:满减策略、折扣策略等各自实现算法。
- 订单上下文:持有当前策略对象,调用时动态执行对应算法。
当新增“双倍积分”促销时,只需添加新策略类,无需修改现有代码。
- 促销策略接口:定义统一的优惠计算接口(如
二、模式结构
- 抽象策略(Strategy):定义算法的公共接口(如
execute()
)。 - 具体策略(ConcreteStrategy):实现具体算法(如加法、折扣)。
- 上下文(Context):维护策略对象引用,提供切换和执行接口。
三、适用场景
- 动态算法切换:如支付方式(微信、支付宝)、排序算法(快排、归并)。
- 消除条件分支:替代大量
if-else
或switch-case
语句。 - 算法复用与扩展:需要独立管理多种算法变体时。
四、优缺点分析
优点 | 缺点 |
---|---|
1. 灵活扩展:新增策略无需修改上下文 | 1. 类数量膨胀:每个策略需独立类 |
2. 消除条件判断:代码更简洁易维护 | 2. 客户端需感知策略存在 |
3. 符合开闭原则:算法与使用解耦 | 3. 性能开销:频繁切换可能影响效率 |
五、代码实现
1. C++ 示例(计算器策略)
#include <iostream>
// 抽象策略:运算接口
class Strategy {
public:
virtual int execute(int a, int b) = 0;
virtual ~Strategy() = default;
};
// 具体策略:加法
class AddStrategy : public Strategy {
public:
int execute(int a, int b) override {
return a + b;
}
};
// 上下文:计算器
class Calculator {
Strategy* strategy;
public:
void setStrategy(Strategy* s) { strategy = s; }
int calculate(int a, int b) {
return strategy->execute(a, b);
}
};
int main() {
Calculator calc;
calc.setStrategy(new AddStrategy());
std::cout << "10 + 5 = " << calc.calculate(10, 5) << std::endl; // 输出15
// 切换策略示例:calc.setStrategy(new SubtractStrategy());
return 0;
}
解析:
- 通过
setStrategy()
动态更换加减乘除算法。
2. Python 示例(促销策略)
from abc import ABC, abstractmethod
class PromotionStrategy(ABC):
@abstractmethod
def calculate(self, price: float) -> float:
pass
class FullReductionStrategy(PromotionStrategy): # 满减策略
def calculate(self, price):
return price - 20 if price >= 100 else price
class DiscountStrategy(PromotionStrategy): # 折扣策略
def calculate(self, price):
return price * 0.8
class Order:
def __init__(self, strategy: PromotionStrategy):
self.strategy = strategy
def checkout(self, price):
return self.strategy.calculate(price)
# 客户端
order = Order(FullReductionStrategy())
print(f"满减后价格:{order.checkout(150)}") # 输出130.0
特点:
- Python支持鸭子类型,无需严格接口继承。
3. Java 示例(支付策略 + 工厂模式)
// 策略接口
interface PaymentStrategy {
void pay(double amount);
}
// 具体策略:微信支付
class WechatPay implements PaymentStrategy {
public void pay(double amount) {
System.out.printf("微信支付:%.2f元\n", amount);
}
}
// 策略工厂(管理实例)
class PaymentFactory {
private static final Map<String, PaymentStrategy> strategies = new HashMap<>();
static {
strategies.put("wechat", new WechatPay());
strategies.put("alipay", new Alipay());
}
public static PaymentStrategy getStrategy(String key) {
return strategies.getOrDefault(key, new DefaultPay());
}
}
// 上下文
class ShoppingCart {
private PaymentStrategy strategy;
public void setStrategy(String key) {
this.strategy = PaymentFactory.getStrategy(key);
}
public void checkout(double amount) {
strategy.pay(amount);
}
}
// 测试
ShoppingCart cart = new ShoppingCart();
cart.setStrategy("wechat");
cart.checkout(99.9); // 输出:微信支付:99.90元
优化点:
- 工厂模式集中管理策略实例,避免重复创建。
六、总结与扩展
策略模式通过算法封装和动态切换实现了高扩展性,特别适合以下场景:
- 电商促销:不同优惠规则独立管理。
- 游戏技能系统:角色动态切换攻击策略。
- 数据解析:支持JSON、XML等多种格式解析器。
扩展技巧:
- 结合享元模式复用无状态策略对象(如线程安全的计算策略)。
- 使用Lambda表达式(Java/Python)简化小型策略类的定义。
-
参考资料
- 策略模式基础结构与角色定义
- 三国锦囊案例与设计思想
- C++策略模式与对象生命周期管理
- Python策略模式与动态语言特性
- Java策略模式与线程安全实践