
1. 工厂方法模式从业务痛点出发的设计哲学作为一名经历过多个支付系统重构的老码农我见过太多因为对象创建逻辑混乱而导致的维护噩梦。最典型的场景莫过于支付渠道的接入——每对接一个新支付平台就要在全网搜索哪里又冒出了new WeChatPay()这样的硬编码。这种代码就像程序里的地雷指不定哪天就会在某个意想不到的地方爆炸。工厂方法模式Factory Method Pattern正是为了解决这类问题而生。它不是什么高深的理论而是无数前辈在踩坑后总结出的最佳实践。其核心思想可以用一句话概括将对象的创建与使用分离。听起来简单但真正理解并运用好这个模式需要从实际业务场景出发。2. 工厂方法模式要解决的核心问题2.1 典型反模式创建逻辑散落各处让我们看一个支付系统的典型反模式# 订单服务中 def create_order(): if config.payment_type wechat: payment WeChatPay() elif config.payment_type alipay: payment AliPay() # 其他业务逻辑 # 退款服务中 def process_refund(): if user.preferred_payment wechat: payment WeChatPay() elif user.preferred_payment alipay: payment AliPay() # 其他业务逻辑这种代码的问题显而易见重复代码相同的创建逻辑散落在各处修改成本高新增支付方式需要修改所有创建点测试困难无法统一mock支付对象2.2 创建逻辑的复杂性演变在实际项目中对象创建很少像new SomeClass()这么简单。以支付系统为例创建支付对象可能涉及根据商户配置选择具体实现初始化SDK配置建立网络连接加载证书设置超时参数这些复杂逻辑如果散落在业务代码中会导致严重的维护问题。3. 工厂方法模式的实现演进3.1 基础版简单工厂class PaymentFactory: staticmethod def create(pay_type: str) - Payment: if pay_type wechat: return WeChatPay( merchant_idconfig.wechat_id, cert_pathconfig.wechat_cert, timeout30 ) elif pay_type alipay: return AliPay( app_idconfig.alipay_appid, private_keyconfig.alipay_key ) raise ValueError(unsupported pay type)这个版本已经解决了创建逻辑集中管理的问题但仍然存在缺陷工厂类仍需修改以支持新支付方式不符合开闭原则对扩展开放对修改关闭3.2 标准工厂方法模式真正的工厂方法模式通过继承来实现扩展from abc import ABC, abstractmethod class PaymentFactory(ABC): abstractmethod def create(self) - Payment: pass class WeChatPayFactory(PaymentFactory): def create(self) - Payment: return WeChatPay( merchant_idconfig.wechat_id, cert_pathconfig.wechat_cert, timeout30 ) class AliPayFactory(PaymentFactory): def create(self) - Payment: return AliPay( app_idconfig.alipay_appid, private_keyconfig.alipay_key )使用方式def process_payment(factory: PaymentFactory): payment factory.create() payment.pay(100) # 根据配置选择工厂 factory WeChatPayFactory() if config.payment_type wechat else AliPayFactory() process_payment(factory)这种实现的优势新增支付方式只需添加新工厂类无需修改已有代码符合开闭原则各工厂可以独立演化3.3 Python风格的工厂方法在Python中我们可以利用语言特性写出更简洁的实现class PaymentFactory: _mapping { wechat: lambda: WeChatPay( merchant_idconfig.wechat_id, cert_pathconfig.wechat_cert, timeout30 ), alipay: lambda: AliPay( app_idconfig.alipay_appid, private_keyconfig.alipay_key ) } classmethod def register(cls, pay_type: str, creator: Callable[[], Payment]): cls._mapping[pay_type] creator classmethod def create(cls, pay_type: str) - Payment: try: return cls._mapping[pay_type]() except KeyError: raise ValueError(fUnsupported payment type: {pay_type}) # 注册新支付方式 PaymentFactory.register(unionpay, lambda: UnionPay(config.unionpay_merchant))这种实现保持了扩展性通过register方法代码更简洁符合Python的鸭子类型哲学4. 工厂方法模式的高级应用4.1 延迟创建与缓存有些对象的创建成本很高可以考虑在工厂中加入缓存class CachedPaymentFactory(PaymentFactory): _instances {} classmethod def create(cls, pay_type: str) - Payment: if pay_type not in cls._instances: cls._instances[pay_type] super().create(pay_type) return cls._instances[pay_type]4.2 参数化工厂当创建逻辑需要动态参数时class ParametrizedPaymentFactory: staticmethod def create(pay_type: str, **kwargs) - Payment: if pay_type wechat: return WeChatPay(**kwargs) elif pay_type alipay: return AliPay(**kwargs) raise ValueError(unsupported pay type)4.3 结合依赖注入在现代框架中工厂方法常与DI容器结合# 使用依赖注入框架如injector inject def process_payment(factory: PaymentFactory Provide[WeChatPayFactory]): payment factory.create() payment.pay(100)5. 工厂方法模式的适用场景与误区5.1 适用场景评估表场景特征适合工厂方法不适合工厂方法对象类型多且可能扩展✅❌对象创建逻辑复杂✅❌需要统一控制创建过程✅❌类型固定且创建简单❌✅运行时才能确定具体类型✅❌5.2 常见误区与解决方案误区1过度设计症状为只有1-2种实现的简单场景引入工厂解决YAGNI原则You Aint Gonna Need It误区2工厂类变成上帝类症状一个工厂类负责创建几十种不相关的对象解决按职责拆分多个工厂误区3忽视线程安全症状在多线程环境中共享有状态的工厂解决使用线程局部变量或每次创建新实例6. 工厂方法在架构中的位置在分层架构中工厂通常位于介于业务逻辑层与基础设施层之间负责将业务需求转换为具体的技术实现作为抽象与具体的桥梁graph TD A[业务逻辑] --|依赖抽象| B[工厂接口] B -- C[具体工厂A] B -- D[具体工厂B] C -- E[具体产品A] D -- F[具体产品B]7. 测试中的工厂方法工厂方法极大改善了可测试性# 测试时可以使用Mock工厂 class MockPaymentFactory(PaymentFactory): def create(self) - Payment: return MockPayment() def test_payment_flow(): processor PaymentProcessor(MockPaymentFactory()) result processor.process(100) assert result.success8. 与其他模式的关系8.1 工厂方法 vs 简单工厂简单工厂一工厂类包含所有创建逻辑工厂方法将创建逻辑分散到子类8.2 工厂方法 vs 抽象工厂工厂方法创建单一产品抽象工厂创建产品族8.3 工厂方法 vs 依赖注入工厂方法主动获取依赖依赖注入被动接收依赖9. 性能考量工厂方法引入的额外开销主要来自额外的间接层通常可忽略动态分配Python中影响很小对象创建本身可通过缓存优化在99%的场景下工厂方法带来的架构收益远大于其性能开销。10. 实战建议渐进式采用从最痛点开始逐步重构命名约定使用XXXFactory明确工厂职责文档完善为每个工厂记录支持的类型和参数监控创建在工厂中添加日志和指标收集避免滥用不是所有new都需要替换为工厂工厂方法模式就像代码中的交通警察它不会改变目的地的位置但能让去往目的地的过程更加有序可控。在实际项目中我见过太多因为忽视对象创建管理而导致的架构腐化。采用工厂方法不是追求设计模式的纯粹性而是为了给项目留下可持续发展的空间。