一、什么是工厂函数?
工厂函数(Factory Function)是一种设计模式,其核心是通过一个函数来 创建并返回对象,而不是直接使用 new
或构造函数实例化对象。它封装了对象的创建过程,使代码更灵活、可维护。
二、工厂函数的目的与作用
目的 | 作用 |
---|---|
解耦对象创建逻辑 | 将对象的创建与使用分离,调用者无需关心对象的具体实现细节。 |
延迟实例化 | 仅在需要时创建对象,避免资源浪费(如内存、CPU)。 |
支持动态参数 | 根据输入参数返回不同类型的对象(多态性)。 |
统一接口 | 提供标准化的对象创建方式,便于扩展和维护。 |
三、工厂函数示例
1. 简单工厂:形状创建
假设需要根据用户输入创建不同形状(圆形、矩形),直接实例化会导致代码冗余和耦合:
# 无工厂函数的问题
if shape_type == 'circle':obj = Circle(radius=5)
elif shape_type == 'rectangle':obj = Rectangle(width=3, height=4)
使用工厂函数优化后:
# 定义形状类
class Circle:def __init__(self, radius):self.radius = radiusclass Rectangle:def __init__(self, width, height):self.width = widthself.height = height# 工厂函数
def shape_factory(shape_type, **kwargs):if shape_type == 'circle':return Circle(**kwargs)elif shape_type == 'rectangle':return Rectangle(**kwargs)else:raise ValueError("Unknown shape type")# 调用
circle = shape_factory('circle', radius=5)
rectangle = shape_factory('rectangle', width=3, height=4)
2. Mininet 中的工厂函数
在 Mininet 自定义拓扑中,lambda: MyTopo()
是一个工厂函数:
# 工厂函数:延迟创建 MyTopo 实例
topos = {'mytopo': (lambda: MyTopo())}
当 Mininet 需要构建拓扑时,会调用 topos['mytopo']()
执行 Lambda 函数,动态生成 MyTopo
实例。
四、工厂函数的优势
1. 避免紧耦合
- 直接实例化:调用方需知道具体类的构造函数。
- 工厂函数:调用方只需传递参数,无需了解类细节。
2. 灵活扩展
新增对象类型时,只需修改工厂函数,无需修改调用代码。
# 扩展支持三角形
class Triangle:def __init__(self, base, height):self.base = baseself.height = heightdef shape_factory(shape_type, **kwargs):# 原有逻辑...elif shape_type == 'triangle':return Triangle(**kwargs)
3. 资源管理
延迟实例化可节省内存和计算资源,尤其是在对象创建成本高时(如数据库连接)。
五、工厂函数 vs 直接实例化
场景 | 直接实例化 | 工厂函数 |
---|---|---|
简单对象创建 | 适合(如 obj = MyClass() ) | 过渡设计 |
复杂/条件化创建 | 代码冗余,难以维护 | 统一管理,逻辑清晰 |
需要延迟加载 | 无法实现 | 天然支持 |
多态性需求 | 需手动判断类型 | 封装在工厂中,对调用方透明 |
六、工厂模式的其他形式
-
工厂方法模式
每个子类实现自己的工厂方法(面向对象设计中的经典模式)。 -
抽象工厂模式
创建一组相关或依赖对象的接口(如 GUI 库中的跨平台组件)。
七、总结
- 核心思想:工厂函数通过封装对象创建逻辑,提升代码的灵活性和可维护性。
- 在 Mininet 中的应用:
lambda: MyTopo()
作为工厂函数,确保 Mininet 在运行时动态创建拓扑实例。 - 适用场景:对象创建逻辑复杂、需要延迟加载或支持多态性时优先使用。
通过合理使用工厂函数,可以显著提高代码的模块化程度,降低系统各部分之间的依赖。