创建型模式怎么选
创建型模式处理的是「怎么造对象」:需要进程内唯一实例用单例,按参数决定创建哪个类型用工厂,参数多需要分步装配用建造者,以既有对象为模板批量产出用原型。选型时有个重要前提:多数创建场景用语言原生手段就够了——构造器、具名参数、依赖注入容器的单实例注册,往往比引入一层模式更清晰。模式在创建逻辑确实存在变化或装配压力时才有价值。
创建型模式对照
| 模式 | 解决什么 | 常见简化替代 |
|---|---|---|
| Singleton | 进程内唯一共享实例 | 依赖注入容器注册单实例 |
| Factory Method | 创建逻辑随类型或环境变化 | 静态工厂函数或具名构造方法 |
| Abstract Factory | 一组相关产品需要成套创建 | 若干工厂函数的组合对象 |
| Builder | 参数多且需要分步装配 | 具名参数或配置对象 |
| Prototype | 以既有对象为模板克隆 | 拷贝构造器 |
典型使用场景
- 按配置决定实现:从配置文件读取类型名后创建对应实现,用工厂集中处理分支
- 测试与生产的依赖差异:由工厂或容器按环境返回不同实现
- 多参数对象装配:构造参数超过五六个且存在可选组合,用建造者分步设置
- 同一族配置的成套创建:需要保证多个相关对象风格一致时用抽象工厂
- 基准对象派生:以已验证的配置为原型复制出多套环境配置
选择顺序建议
选择顺序建议
# 从原生手段开始,出现压力再考虑模式
1. 先用语言原生方式:构造器、具名参数、容器的单实例注册
2. 创建逻辑出现分支(按类型或环境选择) → 工厂
3. 参数装配压力明显(可选组合多) → 建造者
4. 需要以既有对象为模板 → 原型(拷贝构造器)
5. 一组产品必须成套一致 → 抽象工厂判断问句
| 唯一性 | 是否真的需要进程内唯一?还是只需要共享一份配置 |
|---|---|
| 变化点 | 创建逻辑会不会随环境或类型变化 |
| 装配压力 | 构造参数是否多到需要分步或默认值组合 |
| 克隆需求 | 是否以既有实例为模板派生新对象 |
先套模式再找理由是最常见的浪费:为一个只有一种实现的类型引入工厂接口,所有调用点都要经过一层无意义的间接调用,注释里还写着「方便将来扩展」。
建造者与工厂最好分工明确:工厂负责决定造哪一种,建造者负责把选定的那种装配完整。两者混用会导致构造入口重复,使用者不知道应该从哪个入口开始。
落地检查清单
- 创建逻辑的变化点明确,能说清哪种变化触发模式引入
- 原生手段已评估过,确实不够用
- 构造入口唯一,调用方不会在两个入口之间犹豫
- 新增一种类型或配置时,改动范围局限在预期处