Python中重构多IF语句为更简洁实现的方案咨询
重构方案:用注册表模式替代工厂类多IF分支(契合策略模式思想)
策略模式完全适用于你的场景,结合注册表模式可以彻底消除冗余的IF分支,同时保证代码的扩展性与可维护性,以下是具体实现步骤:
1. 定义统一的检索工具抽象基类
先通过抽象基类约束所有检索工具的接口,确保子类实现统一的方法:
from abc import ABC, abstractmethod class BaseRetrievalTool(ABC): @abstractmethod def start_detailed_search(self, query_id: str, request_id: str): """所有检索工具必须实现的核心方法""" pass
2. 实现子类并继承抽象基类
让现有的所有检索工具子类继承上述基类,确保接口一致性:
class UserRetrievalTool(BaseRetrievalTool): def start_detailed_search(self, query_id: str, request_id: str): # 实现用户维度的检索逻辑 print(f"用户检索: query_id={query_id}, request_id={request_id}") class OrderRetrievalTool(BaseRetrievalTool): def start_detailed_search(self, query_id: str, request_id: str): # 实现订单维度的检索逻辑 print(f"订单检索: query_id={query_id}, request_id={request_id}")
3. 用注册表替代IF分支
方案一:静态注册表字典
直接用字典映射工具名称到对应的类,新增工具时只需添加键值对:
# 定义工具注册表,键为原TOOL_NAME常量值,值为对应工具类 RETRIEVAL_TOOL_REGISTRY = { "USER_DETAIL_TOOL": UserRetrievalTool, "ORDER_DETAIL_TOOL": OrderRetrievalTool, # 新增工具时在此处添加即可 } # 重构后的工厂类 class DetailRetrievalFactory: def get_detailed_search_tool(self, tool_name: str) -> BaseRetrievalTool: try: tool_class = RETRIEVAL_TOOL_REGISTRY[tool_name] return tool_class() except KeyError: raise ValueError(f"不支持的检索工具类型: {tool_name}")
方案二:装饰器自动注册(更优雅)
用装饰器自动将子类注册到注册表,新增工具时只需给子类添加装饰器,无需修改注册表字典:
RETRIEVAL_TOOL_REGISTRY = {} def register_retrieval_tool(tool_name: str): def decorator(cls): if tool_name in RETRIEVAL_TOOL_REGISTRY: raise ValueError(f"工具名称 {tool_name} 已被注册") RETRIEVAL_TOOL_REGISTRY[tool_name] = cls return cls return decorator # 子类通过装饰器自动注册 @register_retrieval_tool("USER_DETAIL_TOOL") class UserRetrievalTool(BaseRetrievalTool): def start_detailed_search(self, query_id: str, request_id: str): print(f"用户检索: query_id={query_id}, request_id={request_id}") @register_retrieval_tool("ORDER_DETAIL_TOOL") class OrderRetrievalTool(BaseRetrievalTool): def start_detailed_search(self, query_id: str, request_id: str): print(f"订单检索: query_id={query_id}, request_id={request_id}") # 工厂类逻辑与方案一一致 class DetailRetrievalFactory: def get_detailed_search_tool(self, tool_name: str) -> BaseRetrievalTool: try: tool_class = RETRIEVAL_TOOL_REGISTRY[tool_name] return tool_class() except KeyError: raise ValueError(f"不支持的检索工具类型: {tool_name}")
4. 原有调用逻辑完全兼容
重构后,业务代码的调用方式不需要任何修改:
# 示例调用 tool_name = "USER_DETAIL_TOOL" data_retrieval = DetailRetrievalFactory().get_detailed_search_tool(tool_name) data_retrieval.start_detailed_search("q_123", "req_456")
方案优势
- 彻底消除了冗余的IF分支,代码结构更清晰,维护成本大幅降低
- 新增检索工具时,只需新增子类并完成注册,无需修改工厂类核心逻辑,完全符合开闭原则
- 本质是策略模式的落地实现:将不同检索逻辑(策略)封装为独立子类,通过统一接口调用,注册表则是策略的管理容器
内容的提问来源于stack exchange,提问作者Squiggs.
相关产品推荐
相关产品推荐

