首页/开发/代码质量与评审速查/工厂方法 Factory Method(创建型)
设计原则与模式62 条

工厂方法 Factory Method(创建型)

让子类/实现方决定实例化哪个具体类:调用方依赖创建接口而非具体类型,新增产品时扩展工厂实现即可;简单场景用静态工厂函数与之等效。

工厂方法是什么

工厂方法让子类或实现方决定实例化哪个具体类:调用方依赖创建接口而不是具体类型,新增产品时只扩展工厂实现。简单场景里,静态工厂方法(带名字的创建方法)与它效果等效,只是把创建逻辑收在一个方法中,顺便可以做校验与默认值填充。

基本信息

意图把实例化推迟到实现方
参与者产品接口、工厂、具体工厂
变体静态工厂方法,用名字表达创建语义
收益调用方不依赖具体类,替换实现不改调用点
相关模式抽象工厂用于产品族场景

典型使用场景

  • 同一接口有多个实现,按环境或配置选择
  • 构造过程需要校验与默认值填充
  • 需要给构造函数起更清楚的名字(按标识创建、按配置创建)
  • 创建逻辑需要集中管理,避免散落各处
  • 隔离第三方类型,把具体类限制在工厂内部

Java 示例

Java 示例
abstract class Dialog {
    abstract Button createButton();       // 工厂方法,由子类决定具体产品

    void render() { createButton().paint(); }
}

class WindowsDialog extends Dialog {
    Button createButton() { return new WindowsButton(); }
}

工厂的几种形态

形态适用注意
静态工厂方法需要命名语义或封装校验不要与构造语义混淆
工厂方法(继承)产品族按子类替换子类数量会随产品增长
注册表工厂实现按类型动态选择装配点保持唯一
工厂的价值在于把具体类集中在一处:如果调用方仍在多处直接构造具体实现,工厂只是多包了一层方法,隔离并没有发生。
工厂里写业务分支,会让它逐渐变成什么都管的上帝类:创建之外的计算应该留在各自的实现或服务里。
创建往往伴随依赖:日志、时钟、限流器这些应显式传入工厂,而不是在里面临时创建,否则测试时无从替换,扩展实现也会互相牵连。

易错点

  • 工厂只返回一种实现:接口层空转,可以先退回直接构造
  • 工厂里写业务分支:职责扩散,工厂变成上帝类
  • 调用方绕过工厂直接构造:具体类重新散落各处,替换时仍要全局搜索
  • 静态工厂方法名与构造语义混淆:同名不同行为,调用方容易误用

数据来源与参考

  • 《设计模式》(GoF)· Factory Method
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌