返回已有实例的Python抽象属性是否属于工厂模式?
你的实现属于工厂方法模式的变体,更具体可称为单例工厂
先直接给你结论:你的代码完全符合工厂方法模式的核心定义,只是它结合了单例模式的特性,业内通常把这种实现叫做单例工厂(Singleton Factory),或者更通用的缓存工厂(Cached Factory)。
为什么符合工厂方法模式?
先回到Refactoring Guru的定义:
工厂方法定义了一个方法,该方法应用于创建对象而非直接调用构造函数。子类可重写此方法以改变将创建的对象类。
这里的关键不是“创建新对象”,而是把“决定返回哪个类型的对象”的逻辑延迟到子类——这才是工厂方法模式的核心价值。你的实现完美满足这一点:
- 抽象类
AnimalFactory2定义了返回IAnimal类型的契约(通过抽象属性) - 子类
CatFactory2和DogFactory2分别决定了返回Cat还是Dog的实例
定义里的“创建对象”是广义的,它指的是提供对象实例的逻辑,既可以是每次新建,也可以是返回预先初始化好的实例。工厂方法模式并不强制要求必须生成新实例,它只关注“谁来控制实例的类型”。
和传统工厂方法的区别
传统工厂方法每次调用都会生成新实例,而你的实现是在工厂初始化时创建一次实例,之后重复返回这个实例。这是工厂方法的常见变体,非常适合你的起重机场景——因为起重机的轴是持续存在的实体,不需要每次请求都新建实例,复用已有实例更符合业务逻辑。
更精准的命名
这种返回已有实例的工厂实现,有几个通用的称呼:
- 单例工厂(Singleton Factory):因为每个工厂子类只会返回同一个实例,符合单例的核心特性
- 缓存工厂(Cached Factory):强调工厂内部缓存了实例,避免重复创建
- 实例工厂(Instance Factory):突出它返回的是预先创建好的实例,而非每次新建
结合你的起重机业务场景分析
在你的实际代码中,CraneInterface通过抽象属性返回AxisInterface实现类的设计,是工厂方法模式的合理应用:
- CraneInterface作为抽象工厂角色,定义了获取轴实例的统一契约
- CraneSimulator和CraneOpcuaClient作为具体工厂,分别返回AxisSimulation和真实的OPC UA轴客户端实例
- 选择返回已存在的实例完全符合业务逻辑——起重机的轴是长期运行的实体,复用实例能避免不必要的资源消耗,同时保证状态的一致性
至于你提到的观察者模式,它和这个工厂变体是完全互补的:工厂方法负责提供轴实例,观察者模式负责处理轴状态变化的通知,两者各司其职,完美解决了你的代码复用和状态通知问题。
内容的提问来源于stack exchange,提问作者Blue7
相关产品推荐
相关产品推荐

