在真实项目中,对象的创建往往比使用更复杂。
如果你发现代码中频繁出现if-else或根据参数去new不同的类,那基本已经到了该用工厂方法模式的时候了。
一、工厂方法模式解决什么问题
先看一个非常常见的写法:
defcreate_payment(pay_type):ifpay_type=="wechat":returnWeChatPay()elifpay_type=="alipay":returnAliPay()elifpay_type=="bank":returnBankPay()else:raiseValueError("unsupported pay type")问题很明显:
- 新增一种支付方式,必须修改这个函数
- 创建逻辑与业务逻辑耦合
- 违反开闭原则
工厂方法模式的目的就是:
把“创建对象的逻辑”从使用对象的地方解耦出来。
二、什么是工厂方法模式
**工厂方法模式(Factory Method)**的定义:
定义一个创建对象的接口,让子类决定实例化哪一个类。
核心思想:
- 使用方只依赖抽象
- 创建细节由工厂或子类负责
三、一个最基础的 Python 工厂方法示例
1. 抽象产品
fromabcimportABC,abstractmethodclassPayment(ABC):@abstractmethoddefpay(self,amount):pass2. 具体产品
classWeChatPay(Payment):defpay(self,amount):print(f"微信支付{amount}")classAliPay(Payment):defpay(self,amount):print(f"支付宝支付{amount}")3. 工厂类
classPaymentFactory:@staticmethoddefcreate(pay_type:str)->Payment:ifpay_type=="wechat":returnWeChatPay()ifpay_type=="alipay":returnAliPay()raiseValueError("unsupported pay type")使用方:
payment=PaymentFactory.create("wechat")payment.pay(100)四、为什么这还不够“工厂方法”
上面的写法虽然集中管理了创建逻辑,但:
- 依然需要修改工厂代码
- 本质还是
if-else
真正的工厂方法强调:
通过继承扩展工厂,而不是修改工厂。
五、标准工厂方法模式结构
1. 抽象工厂
classPaymentFactory(ABC):@abstractmethoddefcreate(self)->Payment:pass2. 具体工厂
classWeChatPayFactory(PaymentFactory):defcreate(self)->Payment:returnWeChatPay()classAliPayFactory(PaymentFactory):defcreate(self)->Payment:returnAliPay()使用方式:
factory=WeChatPayFactory()payment=factory.create()payment.pay(100)新增支付方式时:
- 新增产品类
- 新增工厂类
- 无需修改原有代码
六、Python 风格的工厂方法(推荐)
Python 中,很多时候没必要写那么多类。
使用字典 + 类引用
classPaymentFactory:_mapping={"wechat":WeChatPay,"alipay":AliPay,}@classmethoddefcreate(cls,pay_type:str)->Payment:try:returncls._mapping[pay_type]()exceptKeyError:raiseValueError("unsupported pay type")优点:
- 代码简洁
- 易于维护
- 更符合 Python 风格
七、工厂方法 vs 直接实例化
| 对比点 | 直接 new | 工厂方法 |
|---|---|---|
| 扩展性 | 差 | 好 |
| 解耦 | 低 | 高 |
| 可测试性 | 差 | 好 |
| 代码复杂度 | 低 | 中 |
适用原则:
- 对象类型固定、变化少 → 直接实例化
- 对象类型多、变化频繁 → 工厂方法
八、工厂方法常见误区
1. 工厂类变成“上帝类”
- 包含大量 if-else
- 违反单一职责
解决方案:
- 拆分工厂
- 或引入抽象工厂
2. 为了工厂而工厂
- 只有一个实现类
- 没有扩展需求
👉 直接实例化即可。
九、总结
工厂方法模式的核心价值在于:
- 解耦创建与使用
- 遵循开闭原则
- 为系统预留扩展空间
在 Python 中:
- 思想比形式重要
- 不必拘泥 UML 结构
- 用最简单的方式解决创建问题