简单工厂模式 python

一、核心模式:工厂模式(Factory Pattern)+ 注册表模式(Registry Pattern)

这段代码是简单工厂模式(Simple Factory)的典型实现,同时结合了「注册表模式(Registry Pattern)」(也叫注册器模式),属于设计模式中「创建型模式」的组合应用,核心目标是统一管理对象的创建逻辑,通过 “名称 - 类型” 映射动态创建实例。

1. 核心模式的定义

  • 注册表模式:通过一个全局字典(__ACTIONS__)维护「标识(如 Name)- 类(Action 子类)」的映射关系,实现类的动态注册和查找,是工厂模式的基础;
  • 简单工厂模式:通过一个统一的入口方法(from_dict),根据传入的标识(name)从注册表中找到对应类,再创建实例,避免直接使用 new/__init__ 硬编码创建对象。

二、代码补全与逐行解析(模式特征拆解)

先补充完整上下文(修复语法问题 + 补全依赖),再分析核心逻辑:
 
from typing import Type, Dict, Any

# 定义Action基类(补充上下文)
class Action:
    # 注册表核心:存储「Action名称-Action子类」的映射
    __ACTIONS__: Dict[str, Type["Action"]] = {}
    # 每个Action子类需定义的唯一名称属性
    Name: str = ""

    @staticmethod
    def register(atype: Type["Action"]):
        """注册表模式核心:将Action子类注册到全局字典"""
        # 以子类的Name属性为key,类本身为value,存入注册表
        Action.__ACTIONS__[atype.Name] = atype

    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> "Action":
        """工厂模式核心:从注册表动态创建实例"""
        # 从传入的字典中提取Action名称(修复原代码的name/kwargs未定义问题)
        name = data.get("name")  # 假设data中包含"name"字段,对应Action的Name
        kwargs = {k: v for k, v in data.items() if k != "name"}  # 剩余参数作为初始化参数
        # 从注册表中找到对应类,动态创建实例
        return Action.__ACTIONS__[name](**kwargs)

# 示例:定义Action子类并注册
class MoveAction(Action):
    Name = "move"  # 定义唯一名称
    def __init__(self, x: int, y: int):
        self.x = x
        self.y = y

# 注册子类到注册表
Action.register(MoveAction)

# 工厂方法创建实例
data = {"name": "move", "x": 10, "y": 20}
action = Action.from_dict(data)
print(isinstance(action, MoveAction))  # 输出:True
 
 
关键设计点(模式特征):
代码片段模式特征作用
__ACTIONS__: Dict[str, Type["Action"]] 注册表核心 全局字典作为 “类注册表”,存储所有可创建的 Action 子类,是动态创建的基础;
@staticmethod register(atype) 注册表模式 - 注册逻辑 将自定义的 Action 子类(如 MoveAction)注册到注册表,无需修改工厂方法即可扩展新类型;
@classmethod from_dict(data) 工厂模式 - 创建逻辑 统一的实例创建入口:从 data 中提取名称 → 查注册表找对应类 → 动态初始化实例;
Action.__ACTIONS__[name](** kwargs) 动态创建核心 避免硬编码 if name == "move": return MoveAction(),新增 Action 子类只需注册,无需修改工厂方法;
 

三、该模式的核心价值(为什么这么设计)

1. 解决的核心问题

  • 避免硬编码创建逻辑:如果不用工厂 + 注册表,创建实例需要写大量 if-elif(如 if name=="move": return MoveAction()),新增 Action 子类需修改创建逻辑,违反「开闭原则」;
  • 统一管理类的创建:所有 Action 实例都通过 from_dict 创建,便于统一添加日志、参数校验、异常处理等通用逻辑;
  • 动态扩展:新增 Action 子类(如 StopAction)只需定义类 + 调用 register 注册,无需修改原有代码,符合 “对扩展开放、对修改关闭” 的设计原则。

2. 与其他工厂模式的区别(避免混淆)

 
工厂模式类型核心特征你的代码对应关系
简单工厂模式 一个工厂方法创建所有类型实例 from_dict 是唯一的工厂方法,创建所有 Action 子类实例
工厂方法模式 每个产品类型对应一个工厂子类 你的代码未用到(更复杂,适合产品层级多的场景)
抽象工厂模式 创建一组相关产品 你的代码未用到(适合多产品族场景)
 
你的代码是「简单工厂模式 + 注册表模式」:注册表解决 “类的动态映射”,简单工厂解决 “统一创建入口”,是工业级代码中最常用的轻量工厂实现。

四、典型适用场景

这种模式广泛用于需要「动态扩展、统一创建」的场景,比如:
  1. 工业控制软件(如 KUKA 机器人的动作指令:移动、停止、抓取等,新增指令只需注册);
  2. 配置化实例创建(从 JSON/YAML 配置文件读取参数,动态创建对应类实例);
  3. 插件化系统(插件的注册和创建,如你之前的 Plugin 体系);
  4. 序列化 / 反序列化(从字典 / JSON 还原为不同类型的对象)。 

五、原代码的小问题(新手避坑)

原代码存在 2 个语法 / 逻辑问题,已在完整代码中修复:
  1. from_dictnamekwargs 未定义:需从 data 中提取(如 name = data["name"]);
  2. 未定义 __ACTIONS__ 字典:需在 Action 类中初始化这个注册表容器;
  3. 未明确 atype.Name 的来源:需保证每个 Action 子类都定义 Name 类属性。

总结

  1. 核心模式:简单工厂模式 + 注册表模式(创建型模式组合);
  2. 核心逻辑:先通过 register 将 Action 子类注册到全局注册表(__ACTIONS__),再通过 from_dict 从注册表中根据名称动态创建实例;
  3. 核心价值:解耦实例创建逻辑与具体类,支持动态扩展,符合开闭原则;
  4. 典型场景:配置化创建对象、插件注册与实例化、工业控制的指令系统。

posted on 2026-03-18 15:40  limingqi  阅读(4)  评论(0)    收藏  举报

导航