Python 策略模式

Python 中的策略模式(Strategy Pattern)

策略模式是一种行为型设计模式,其核心目的是:
定义一系列算法(策略),把它们一个个封装起来,并且使它们可以相互替换。策略模式让算法的变化独立于使用算法的客户端。

形象比喻:就像出行方式——你可以选择“开车”、“骑自行车”、“坐公交”作为出行策略,客户端(你)只需说“我要出行”,具体用哪种方式可以在运行时切换。

策略模式的优点

  • 开闭原则:新增策略无需修改客户端代码
  • 消除条件判断:避免一大堆 if-elif-else
  • 复用性高:策略可以独立测试和复用
  • 运行时灵活切换:动态选择不同行为

典型应用场景

  • 排序算法选择(快速排序、归并排序、冒泡排序)
  • 支付方式(支付宝、微信、银行卡)
  • 压缩算法(ZIP、GZIP、RAR)
  • 路径规划(最短路径、最快路径、避开收费站)
  • 验证规则(不同表单的不同校验策略)
  • 优惠计算(满减、打折、买赠)

Python 实现示例:支付系统

from abc import ABC, abstractmethod

# 策略接口(Strategy)
class PaymentStrategy(ABC):
    @abstractmethod
    def pay(self, amount: float) -> str:
        pass

# 具体策略1:支付宝支付
class AlipayPayment(PaymentStrategy):
    def pay(self, amount: float) -> str:
        return f"通过支付宝支付 ¥{amount:.2f} 元(手续费 0.6%)"

# 具体策略2:微信支付
class WechatPayment(PaymentStrategy):
    def pay(self, amount: float) -> str:
        return f"通过微信支付 ¥{amount:.2f} 元(手续费 0%)"

# 具体策略3:银行卡支付
class BankCardPayment(PaymentStrategy):
    def __init__(self, card_number: str):
        self.card_number = card_number

    def pay(self, amount: float) -> str:
        masked = "*" * 12 + self.card_number[-4:]
        return f"通过银行卡 {masked} 支付 ¥{amount:.2f} 元(手续费 1%)"

# 上下文(Context):持有策略引用
class ShoppingCart:
    def __init__(self):
        self.items = []
        self._payment_strategy: PaymentStrategy = None

    def add_item(self, name: str, price: float):
        self.items.append((name, price))

    def total_amount(self) -> float:
        return sum(price for _, price in self.items)

    def set_payment_strategy(self, strategy: PaymentStrategy):
        self._payment_strategy = strategy

    def checkout(self):
        if not self._payment_strategy:
            return "请先选择支付方式!"

        amount = self.total_amount()
        result = self._payment_strategy.pay(amount)
        print(f"订单总金额: ¥{amount:.2f}")
        print(result)
        print("支付成功!\n")
        return result

# 客户端使用(运行时自由切换策略)
if __name__ == "__main__":
    cart = ShoppingCart()
    cart.add_item("Python编程书籍", 89.0)
    cart.add_item("机械键盘", 599.0)
    cart.add_item("显示器", 1299.0)

    # 策略1:支付宝支付
    cart.set_payment_strategy(AlipayPayment())
    cart.checkout()

    # 策略2:微信支付
    cart.set_payment_strategy(WechatPayment())
    cart.checkout()

    # 策略3:银行卡支付
    cart.set_payment_strategy(BankCardPayment("6222021234567890"))
    cart.checkout()

输出

订单总金额: ¥1987.00
通过支付宝支付 ¥1987.00 元(手续费 0.6%)
支付成功!

订单总金额: ¥1987.00
通过微信支付 ¥1987.00 元(手续费 0%)
支付成功!

订单总金额: ¥1987.00
通过银行卡 ****7890 支付 ¥1987.00 元(手续费 1%)
支付成功!

Pythonic 更简洁实现:函数作为策略

Python 是动态语言,函数就是一等公民,可以用简单函数代替类来实现策略(推荐在策略简单时使用)。

from typing import Callable

# 定义策略类型
PaymentFunction = Callable[[float], str]

def alipay_pay(amount: float) -> str:
    return f"支付宝支付 ¥{amount:.2f}"

def wechat_pay(amount: float) -> str:
    return f"微信支付 ¥{amount:.2f}(免手续费)"

def credit_card_pay(card_number: str):
    def inner(amount: float) -> str:
        masked = "*" * 12 + card_number[-4:]
        return f"信用卡 {masked} 支付 ¥{amount:.2f}"
    return inner

class SimpleCart:
    def __init__(self):
        self.total = 0
        self.pay_func: PaymentFunction = None

    def set_total(self, total: float):
        self.total = total

    def set_strategy(self, strategy: PaymentFunction):
        self.pay_func = strategy

    def pay(self):
        if self.pay_func:
            print(self.pay_func(self.total))

# 使用
cart = SimpleCart()
cart.set_total(999.0)

cart.set_strategy(alipay_pay)
cart.pay()

cart.set_strategy(wechat_pay)
cart.pay()

card_strategy = credit_card_pay("1234567890123456")
cart.set_strategy(card_strategy)
cart.pay()

甚至更简单:用字典映射策略

strategies = {
    "alipay": alipay_pay,
    "wechat": wechat_pay,
    "card": credit_card_pay("6222xxxxxxxxxxxx")
}

payment_type = "wechat"
strategies[payment_type](999.0)

策略模式结构总结

角色说明
Strategy抽象策略接口(PaymentStrategy)
ConcreteStrategy具体策略(AlipayPayment 等)
Context上下文,持有策略引用(ShoppingCart)

策略模式 vs 其他模式对比

模式目的是否运行时切换典型场景
策略算法可替换支付、排序、压缩
状态对象状态变化导致行为变化订单状态机
命令将请求封装为对象撤销、重做
模板方法定义算法骨架,子类实现步骤否(继承)固定流程的可变部分

Python 中的实用建议

  • 策略简单:直接用函数或 lambda(最 Pythonic)
  • 策略复杂或有状态:用类实现
  • 大量策略:用字典或注册机制管理
  • 结合枚举(Enum)更清晰:
from enum import Enum

class PaymentType(Enum):
    ALIPAY = AlipayPayment()
    WECHAT = WechatPayment()

cart.set_payment_strategy(PaymentType.ALIPAY.value)

真实项目中的例子

  • Django/Form 的字段验证策略
  • Pandas 的 groupby().agg() 支持多种聚合函数
  • 机器学习模型选择(不同算法作为策略)
  • 游戏 AI 行为切换(攻击、防御、逃跑策略)

策略模式是消除条件判断实现行为可插拔的利器,在 Python 中由于函数式特性,实现起来特别优雅。

如果你想看更多实战例子(如排序策略、折扣计算策略、路径规划策略),或者如何与工厂模式结合使用,随时告诉我!

文章已创建 3511

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部