DEV Community

架构师小白
架构师小白

Posted on

策略模式深度指南:让算法策略自由切换的艺术

策略模式深度指南:让算法策略自由切换的艺术

在软件开发中,我们经常面临需要在运行时根据不同情况选择不同算法的场景。比如:电商系统针对不同用户提供不同的折扣计算方式;支付系统根据用户选择的支付渠道执行不同的支付逻辑;日志系统根据环境选择不同的日志输出方式。

这些场景的共同特点是:需要在运行时动态选择算法,而不是在编译时固定。策略模式正是解决这类问题的利器。

什么是策略模式?

策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列算法,并将每个算法封装起来,使它们可以互相替换。策略模式让算法的变化独立于使用算法的客户。

核心角色

  1. 策略接口(Strategy): 定义了所有具体策略的公共接口
  2. 具体策略(Concrete Strategy): 实现具体的算法
  3. 上下文(Context): 持有策略引用,负责调用具体算法

代码实现

假设我们需要为一个电商系统实现多种折扣策略:

from abc import ABC, abstractmethod
from typing import List

# 策略接口
class DiscountStrategy(ABC):
    @abstractmethod
    def calculate(self, original_price: float) -> float:
        pass

# 具体策略:无折扣
class NoDiscount(DiscountStrategy):
    def calculate(self, original_price: float) -> float:
        return original_price

# 具体策略:固定金额折扣
class FixedAmountDiscount(DiscountStrategy):
    def __init__(self, amount: float):
        self.amount = amount

    def calculate(self, original_price: float) -> float:
        return max(0, original_price - self.amount)

# 具体策略:百分比折扣
class PercentageDiscount(DiscountStrategy):
    def __init__(self, percentage: float):
        self.percentage = percentage

    def calculate(self, original_price: float) -> float:
        return original_price * (1 - self.percentage / 100)

# 具体策略:阶梯折扣
class TieredDiscount(DiscountStrategy):
    def __init__(self, tiers: List[tuple]):
        self.tiers = sorted(tiers, key=lambda x: x[0], reverse=True)

    def calculate(self, original_price: float) -> float:
        for threshold, discount in self.tiers:
            if original_price >= threshold:
                return original_price * (1 - discount / 100)
        return original_price

# 上下文
class PriceCalculator:
    def __init__(self, strategy: DiscountStrategy):
        self.strategy = strategy

    def set_strategy(self, strategy: DiscountStrategy):
        self.strategy = strategy

    def calculate_price(self, original_price: float) -> float:
        return self.strategy.calculate(original_price)

# 使用示例
if __name__ == "__main__":
    calculator = NoDiscount()
    print(f"No discount: {calculator.calculate(1000)}")

    calculator = FixedAmountDiscount(100)
    print(f"Fixed discount: {calculator.calculate(1000)}")

    calculator = PercentageDiscount(20)
    print(f"Percentage discount: {calculator.calculate(1000)}")

    calculator = TieredDiscount([(500, 10), (1000, 20), (2000, 30)])
    print(f"Tiered discount 1000: {calculator.calculate(1000)}")
    print(f"Tiered discount 2500: {calculator.calculate(2500)}")
Enter fullscreen mode Exit fullscreen mode

策略模式的优缺点

优点

  1. 开闭原则: 新增策略不影响现有代码
  2. 消除条件语句: 避免大量的 if-else 或 switch-case
  3. 运行时切换: 可以在运行时灵活更换算法
  4. 提高复用性: 相关算法可以重复使用

缺点

  1. 增加类数量: 每个策略都需要一个类
  2. 客户端需了解策略差异: 需要知道各策略的区别
  3. 增加复杂度: 对于简单场景可能过度设计

实际应用场景

  1. 支付方式选择: 支付宝、微信、银行卡等多种支付方式
  2. 排序算法选择: 快速排序、归并排序、堆排序,根据数据特点选择
  3. 验证规则: 不同业务场景使用不同的验证逻辑
  4. 压缩算法: 根据文件类型选择 ZIP、GZIP、Bzip2 等

总结

策略模式是一种强大的行为型设计模式,它将算法封装成独立的对象,使我们可以动态地选择和使用不同的算法。在面对需要多种算法或行为的场景时,考虑使用策略模式来提高代码的可维护性和灵活性。记住:封装变化是设计模式的核心思想,而策略模式正是这一思想的典型体现。

Top comments (0)