Python策略模式如何无需if-else实现CLI参数动态选择对应策略类
实现方案
核心思路
利用字符串到策略类的映射表消除硬编码的if-else分支,后续新增策略仅需更新映射关系,完全符合策略模式的开闭原则。
方案1:手动映射字典(最简实现)
这是最容易理解和实现的方案,适合策略数量不多的场景,完整代码如下:
from abc import ABC, abstractmethod import argparse # 修正原抽象类未继承ABC的问题 class TransportStrategy(ABC): @abstractmethod def transport(self): pass class User(): def __init__(self, transport_strategy): self.transport_strategy = transport_strategy def transport(self): self.transport_strategy.transport() class WalkStrategy(TransportStrategy): def transport(self): print("I walk") class FlyStrategy(TransportStrategy): def transport(self): print("I fly") # 策略名称到类的映射表,新增策略只需在此添加对应键值对 STRATEGY_MAP = { "walk": WalkStrategy, "fly": FlyStrategy } if __name__ == "__main__": # 解析CLI参数 parser = argparse.ArgumentParser() parser.add_argument("--strategy", required=True, help="指定出行策略,支持的选项:walk/fly") args = parser.parse_args() # 直接查表获取策略类,完全消除if-else分支 strategy_key = args.strategy.lower() if strategy_key not in STRATEGY_MAP: raise ValueError(f"不支持的策略,可选值为:{','.join(STRATEGY_MAP.keys())}") strategy = STRATEGY_MAP[strategy_key]() # 执行业务逻辑 user = User(strategy) user.transport()
方案2:自动注册装饰器(更易扩展)
如果策略数量多、迭代频繁,可以用装饰器实现自动注册,新增策略时不需要手动修改映射表,降低漏改概率:
from abc import ABC, abstractmethod import argparse STRATEGY_MAP = {} # 定义策略注册装饰器 def register_strategy(name): def wrapper(cls): STRATEGY_MAP[name] = cls return cls return wrapper class TransportStrategy(ABC): @abstractmethod def transport(self): pass class User(): def __init__(self, transport_strategy): self.transport_strategy = transport_strategy def transport(self): self.transport_strategy.transport() # 新增策略只需加装饰器即可自动注册,无需修改其他代码 @register_strategy("walk") class WalkStrategy(TransportStrategy): def transport(self): print("I walk") @register_strategy("fly") class FlyStrategy(TransportStrategy): def transport(self): print("I fly") if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("--strategy", required=True, help="指定出行策略,支持的选项:walk/fly") args = parser.parse_args() strategy_key = args.strategy.lower() if strategy_key not in STRATEGY_MAP: raise ValueError(f"不支持的策略,可选值为:{','.join(STRATEGY_MAP.keys())}") strategy = STRATEGY_MAP[strategy_key]() user = User(strategy) user.transport()
使用方式
执行以下命令即可指定策略运行:
python example.py --strategy=fly # 输出:I fly python example.py --strategy=walk # 输出:I walk
内容的提问来源于stack exchange,提问作者Wai
相关产品推荐
相关产品推荐

