创建型设计模式
——对象诞生的控制权与系统稳定性
一、为什么需要创建型模式(第一性原理)
在软件系统中,对象的创建并不是一个“语法问题”,而是一个架构控制问题。
创建型模式解决的核心不是“如何 new 对象”,而是:谁来控制对象的诞生方式、创建时机与生命周期?
当系统规模扩大,对象创建会暴露出三个根本性风险:
变化失控
- 产品类型变化
- 构造过程变化
- 内部结构变化
复杂性泄漏
- 构造参数过多
- 校验逻辑分散
- 对象可能处于非法状态
生命周期失序
- 全局对象泛滥
- 隐式依赖
- 并发与销毁问题
👉 创建型模式的本质目标:
将“对象如何诞生”的不稳定性,从业务逻辑中隔离出来,并集中到可治理、可演进的位置。
二、创建型模式的稳定抽象框架
从原理层看,所有创建型模式都在回答同一组问题:
| 维度 | 核心问题 |
|---|---|
| 创建时机 | 立即创建?延迟创建?按需创建? |
| 创建复杂度 | 一步完成?多步构造?复制生成? |
| 生命周期 | 短生命周期?长生命周期?全局唯一? |
| 变化来源 | 类型变化?结构变化?产品族变化? |
不同模式 = 对这些变量的不同控制策略
三、构建复杂对象:Builder(建造者)
1. 设计动机(原理层)
当一个对象的创建:
- 构造参数过多
- 参数之间存在约束关系
- 构造步骤有顺序与组合变化
- 对象希望保持不可变
此时,“构造函数”已不再是合适的抽象。
Builder 的本质:将“构建过程”从“最终表示”中剥离出来
2. 核心思想(架构层)
Builder 引入三个角色分离关注点:
| 角色 | 责任 |
|---|---|
| Builder | 定义构建步骤 |
| ConcreteBuilder | 实现具体构建细节 |
| Director | 控制构建顺序 |
👉 控制权变化:对象不再“被一次性构造”,而是“被过程性组装”。
3. Builder 解决的不是“复杂”,而是“可变复杂”
Builder 适用于:
- 构建步骤 ≥ 3
- 步骤顺序可能变化
- 同一过程生成不同表示
而不适用于:
- 简单 DTO
- 结构稳定、无约束的对象
4. 工程示例(实现层)
interface Builder { Builder process1(); Builder process2(); Builder process3(); Product build();}Director 将构建逻辑集中:
public Product constructProduct(Builder builder){ builder.process1(); builder.process2(); builder.process3(); return builder.build();}四、封装“类型变化”:工厂体系
1. 工厂模式的统一抽象
工厂模式的本质不是“替你 new”,而是:将“产品类型变化”从使用方隔离出去
2. 简单工厂:集中决策(但不可扩展)
优点:
- 使用方无需关心具体类
根本问题:
- 决策逻辑集中
- 违反开闭原则
👉 适合小系统,不适合演进型系统
3. 工厂方法:延迟实例化到子类
将“创建哪个产品”的决策权,下放到子类
核心思想:
- 父类定义使用流程
- 子类决定具体产品
这使得:
- 新产品通过新增子类完成
- 原有逻辑无需修改
👉 工厂方法本质上是一种“创建逻辑的多态化”
4. 抽象工厂:控制产品族一致性
抽象工厂解决的是更高阶的问题:
不是“创建一个产品”,而是“创建一组相互依赖、风格一致的产品”
典型场景:
- UI 组件族
- 跨平台适配
- 数据库驱动族
⚠️ 代价:
- **扩展产品族容易**
- **扩展产品种类困难**
5. 工厂体系的稳定认知总结
| 模式 | 控制的变化 |
|---|---|
| 简单工厂 | 创建参数 |
| 工厂方法 | 产品类型 |
| 抽象工厂 | 产品族一致性 |
五、复制而非构造:Prototype(原型)
1. 原理动机
当对象:
- 创建成本高
- 同类对象差异小
- 构建步骤复杂但稳定
此时,“重新构建”是一种浪费。
原型模式的核心思想:用已有实例作为创建模板
2. Prototype 的真正价值
- 运行期动态改变对象种类
- 快速生成配置化对象
- 避免复杂构造链
但其风险在于:
- 深拷贝成本
- 状态一致性
- 引用对象共享问题
3. 工程实现要点
@Overrideprotected Object clone() throws CloneNotSupportedException { Product product = (Product) super.clone(); product.part1 = (Part1) part1.clone(); return product;}👉 原型的难点不在 clone,而在“复制语义是否正确”
六、全局唯一与生命周期治理:Singleton
1. Singleton 的真实定位
Singleton 解决的不是“创建问题”,而是**“全局生命周期失控问题”**
它本质上是一种:
- 生命周期管理手段
- 全局访问策略
2. 单例的工程实现方式(实现层)
- 饿汉式:简单、安全,但无延迟加载
- 懒汉式:需处理并发
- 静态内部类:推荐方案
- 枚举:JVM 级保障
- 双重检查锁:并发优化方案
这些都是实现策略,而非设计本身。
3. Singleton 的系统性问题(原理层)
- 隐藏依赖关系
- 破坏可测试性
- 引入全局状态
- 阻碍演进为多实例
👉 Singleton 往往是“阶段性方案”,而非终局设计
4. 演进路径
Singleton ↓Factory + 配置 ↓DI 容器 ↓显式生命周期管理七、创建型模式的统一对照(稳定知识)
| 模式 | 核心控制点 | 主要代价 |
|---|---|---|
| Builder | 构建过程 | 引入额外对象 |
| Factory Method | 产品类型 | 类数量增加 |
| Abstract Factory | 产品族 | 扩展受限 |
| Prototype | 创建成本 | 拷贝复杂 |
| Singleton | 生命周期 | 全局状态 |
关联内容(自动生成)
- [/软件工程/设计模式/设计模式.html](/软件工程/设计模式/设计模式.html) 介绍了设计模式的基本概念、关键属性和演化规律,是理解创建型模式的基础
- [/软件工程/设计模式/结构型模式.html](/软件工程/设计模式/结构型模式.html) 与创建型模式共同构成设计模式体系,结构型模式关注类和对象的组合,与创建型模式的对象创建问题相辅相成
- [/软件工程/设计模式/行为模式.html](/软件工程/设计模式/行为模式.html) 与创建型模式共同构成完整的GOF设计模式体系,行为模式关注对象间的职责分配,与创建型模式的对象创建问题形成互补
- [/软件工程/领域驱动设计.html](/软件工程/领域驱动设计.html) 中提到了工厂模式在领域驱动设计中的应用,创建型模式在领域模型构建中发挥重要作用
- [/编程语言/JAVA/框架/Spring/Spring.html](/编程语言/JAVA/框架/Spring/Spring.html) Spring框架中的依赖注入和控制反转体现了创建型模式的思想,特别是工厂模式的应用
- [/软件工程/架构模式/分层架构.html](/软件工程/架构模式/分层架构.html) 分层架构中的设计模式与创建型模式相关,特别是在对象创建和生命周期管理方面
- [/操作系统/操作系统设计.html](/操作系统/操作系统设计.html) 操作系统设计中也包含创建型模式的思想,如对象管理、资源分配等
- [/编程语言/JAVA/JAVA并发编程/并发集合.html](/编程语言/JAVA/JAVA并发编程/并发集合.html) 并发集合的实现中使用了创建型模式来管理对象的创建和生命周期
- [/软件工程/架构/系统设计/高并发.html](/软件工程/架构/系统设计/高并发.html) 高并发系统设计中大量使用创建型模式来处理性能和扩展性问题,如对象池等
- [/中间件/消息队列/消息队列.html](/中间件/消息队列/消息队列.html) 消息队列中也涉及创建型模式,如生产者对象的创建和管理