python中两种策略模式的实现

  1. 基于接口/抽象类的实现(含继承)

这是经典策略模式的定义方式,必然包含继承关系

python 复制代码
from abc import ABC, abstractmethod

# 抽象策略类(必须继承)
class TextSplitterStrategy(ABC):
    @abstractmethod
    def split(self, text: str) -> list[str]:
        pass

# 具体策略类(继承抽象类)
class RecursiveSplitter(TextSplitterStrategy):
    def split(self, text: str) -> list[str]:
        # 实现递归分割逻辑
        return chunks

class TokenSplitter(TextSplitterStrategy):
    def split(self, text: str) -> list[str]:
        # 实现按token分割逻辑
        return chunks

# 上下文类(选择策略)
class TextProcessor:
    def __init__(self, strategy: TextSplitterStrategy):
        self._strategy = strategy
    
    def process(self, text: str) -> list[str]:
        return self._strategy.split(text)

继承关系

python 复制代码
TextSplitterStrategy (抽象基类)
├── RecursiveSplitter
├── TokenSplitter
└── OtherSplitters
实际使用方法:

方式1:运行时动态指定策略(显式选择)

适用场景 :需要在代码中根据不同条件灵活切换策略
操作方法

  1. 在创建 TextProcessor 时,显式传入具体的策略实例

  2. 策略实例可通过条件判断、配置参数或用户输入决定

python 复制代码
# 根据不同条件选择策略
if use_case == "code":
    strategy = TokenSplitter()  # 选择Token分割策略
elif use_case == "document":
    strategy = RecursiveSplitter()  # 选择递归分割策略
else:
    strategy = DefaultSplitter()

# 创建处理器并传入策略
processor = TextProcessor(strategy=strategy)

# 使用处理器
result = processor.process("your_text_here")

方式2:通过工厂类/函数封装选择逻辑(隐式选择)

适用场景 :希望隐藏策略选择细节,简化调用方代码
操作方法

  1. 定义一个策略工厂函数或类

  2. 根据输入参数(如字符串标识)返回对应策略

python 复制代码
def get_splitter(strategy_name: str) -> TextSplitterStrategy:
    """策略工厂函数"""
    strategies = {
        "recursive": RecursiveSplitter,
        "token": TokenSplitter,
        # 可扩展其他策略...
    }
    if strategy_name not in strategies:
        raise ValueError(f"Unknown strategy: {strategy_name}")
    return strategies[strategy_name]()

# 使用工厂创建策略
strategy = get_splitter("token")  # 通过字符串标识选择
processor = TextProcessor(strategy=strategy)
result = processor.process("your_text_here")
2. 基于函数的实现(无继承)

Python支持函数作为一等对象,策略模式可以完全不用继承

python 复制代码
# 策略定义为普通函数
def recursive_split(text: str) -> list[str]:
    return chunks

def token_split(text: str) -> list[str]:
    return chunks

# 上下文通过函数调用选择策略
class TextProcessor:
    def __init__(self, split_strategy: callable):
        self._split = split_strategy
    
    def process(self, text: str) -> list[str]:
        return self._split(text)

无继承关系,仅依赖函数签名一致性(鸭子类型)。

基础使用方式

1. 直接传递策略函数
python 复制代码
# 定义策略函数
def recursive_split(text: str) -> list[str]:
    """递归分割策略"""
    return [text[i:i+100] for i in range(0, len(text), 100)]  # 示例:每100字符分割

def token_split(text: str) -> list[str]:
    """Token分割策略"""
    return text.split()  # 示例:按空格分词

# 创建处理器时注入策略函数
processor = TextProcessor(split_strategy=recursive_split)  # 使用递归分割

# 处理文本
result = processor.process("这是一段需要分割的文本,长度超过100个字符时应自动分割...")
print(result)

进阶使用方式

(1) 带参数的策略函数
python 复制代码
# 策略函数支持参数
def dynamic_split(text: str, chunk_size: int = 50) -> list[str]:
    return [text[i:i+chunk_size] for i in range(0, len(text), chunk_size)]

# 使用functools.partial绑定参数
from functools import partial

# 创建固定参数的策略
custom_split = partial(dynamic_split, chunk_size=30)
processor = TextProcessor(split_strategy=custom_split)

(2) 策略工厂函数

python 复制代码
def get_strategy(strategy_name: str, **params) -> callable:
    """策略工厂"""
    strategies = {
        "recursive": recursive_split,
        "token": token_split,
        "dynamic": dynamic_split
    }
    
    if strategy_name == "dynamic":
        return partial(dynamic_split, **params)
    return strategies[strategy_name]

# 通过工厂获取策略
strategy = get_strategy("dynamic", chunk_size=40)
processor = TextProcessor(strategy)