10.5.2 创建型设计模式
📝 学习目标
- 理解创建型模式的作用和特点
- 掌握5种创建型模式的结构和实现
- 能够根据场景选择合适的创建型模式
- 了解各模式的优缺点和适用场景
🎯 创建型模式概述
什么是创建型模式
创建型模式:关注对象的创建过程,将对象的创建和使用分离
解决的问题
- 创建复杂性:简化复杂对象的创建过程
- 创建灵活性:提供多种创建方式
- 系统独立性:使系统独立于对象的创建方式
5种创建型模式
| 模式 | 英文名 | 作用 | 关键词 |
|---|---|---|---|
| 单例模式 | Singleton | 确保类只有一个实例 | 唯一实例 |
| 工厂方法模式 | Factory Method | 创建对象的接口 | 延迟创建 |
| 抽象工厂模式 | Abstract Factory | 创建相关对象族 | 产品族 |
| 建造者模式 | Builder | 构建复杂对象 | 分步构建 |
| 原型模式 | Prototype | 通过复制创建对象 | 克隆 |
🏗️ 1. 单例模式 (Singleton)
模式意图
确保一个类只有一个实例,并提供全局访问点。
结构图
┌─────────────────┐
│ Singleton │
├─────────────────┤
│ - instance │
├─────────────────┤
│ + getInstance() │
│ - Singleton() │
└─────────────────┘实现方式
1. 饿汉式(线程安全)
java
public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}2. 懒汉式(双重检查锁定)
java
public class Singleton {
private static volatile Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}应用场景
- 数据库连接池
- 日志记录器
- 配置文件管理器
- 线程池
🏭 2. 工厂方法模式 (Factory Method)
模式意图
定义创建对象的接口,让子类决定实例化哪个类。
结构图
Creator Product
┌─────────────────┐ ┌─────────────────┐
│ + factoryMethod()│◄──────►│ │
│ + operation() │ └─────────────────┘
└─────────────────┘ △
△ │
│ │
┌─────────────────┐ ┌─────────────────┐
│ ConcreteCreator │ │ ConcreteProduct │
├─────────────────┤ └─────────────────┘
│ + factoryMethod()│
└─────────────────┘代码实现
java
// 抽象产品
abstract class Product {
public abstract void use();
}
// 具体产品
class ConcreteProductA extends Product {
public void use() {
System.out.println("使用产品A");
}
}
class ConcreteProductB extends Product {
public void use() {
System.out.println("使用产品B");
}
}
// 抽象工厂
abstract class Creator {
public abstract Product factoryMethod();
public void operation() {
Product product = factoryMethod();
product.use();
}
}
// 具体工厂
class ConcreteCreatorA extends Creator {
public Product factoryMethod() {
return new ConcreteProductA();
}
}
class ConcreteCreatorB extends Creator {
public Product factoryMethod() {
return new ConcreteProductB();
}
}应用场景
- 数据库驱动程序
- 日志记录器(文件、数据库、网络)
- 图形界面组件
🏢 3. 抽象工厂模式 (Abstract Factory)
模式意图
提供创建一系列相关或相互依赖对象的接口。
结构图
AbstractFactory AbstractProductA AbstractProductB
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ + createProductA()│────►│ │ │ │
│ + createProductB()│────►└─────────────────┘ └─────────────────┘
└─────────────────┘ △ △
△ │ │
│ ┌─────────────────┐ ┌─────────────────┐
┌─────────────────┐ │ ConcreteProductA1│ │ ConcreteProductB1│
│ ConcreteFactory1│ └─────────────────┘ └─────────────────┘
├─────────────────┤ △ △
│ + createProductA()│ │ │
│ + createProductB()│ ┌─────────────────┐ ┌─────────────────┐
└─────────────────┘ │ ConcreteProductA2│ │ ConcreteProductB2│
└─────────────────┘ └─────────────────┘代码实
现
java
// 抽象产品族
interface Button {
void paint();
}
interface Checkbox {
void paint();
}
// Windows产品族
class WindowsButton implements Button {
public void paint() {
System.out.println("Windows风格按钮");
}
}
class WindowsCheckbox implements Checkbox {
public void paint() {
System.out.println("Windows风格复选框");
}
}
// Mac产品族
class MacButton implements Button {
public void paint() {
System.out.println("Mac风格按钮");
}
}
class MacCheckbox implements Checkbox {
public void paint() {
System.out.println("Mac风格复选框");
}
}
// 抽象工厂
interface GUIFactory {
Button createButton();
Checkbox createCheckbox();
}
// 具体工厂
class WindowsFactory implements GUIFactory {
public Button createButton() {
return new WindowsButton();
}
public Checkbox createCheckbox() {
return new WindowsCheckbox();
}
}
class MacFactory implements GUIFactory {
public Button createButton() {
return new MacButton();
}
public Checkbox createCheckbox() {
return new MacCheckbox();
}
}应用场景
- 跨平台GUI组件
- 数据库访问组件(MySQL、Oracle、SQL Server)
- 游戏中的不同主题界面
🔨 4. 建造者模式 (Builder)
模式意图
将复杂对象的构建与表示分离,使同样的构建过程可以创建不同的表示。
结构图
Director Builder
┌─────────────────┐ ┌─────────────────┐
│ + construct() │───►│ + buildPartA() │
└─────────────────┘ │ + buildPartB() │
│ + getResult() │
└─────────────────┘
△
│
┌─────────────────┐ ┌─────────────────┐
│ ConcreteBuilder │───►│ Product │
├─────────────────┤ └─────────────────┘
│ + buildPartA() │
│ + buildPartB() │
│ + getResult() │
└─────────────────┘代码实现
java
// 产品类
class Computer {
private String cpu;
private String memory;
private String storage;
private String graphics;
// 构造函数和getter/setter方法
public void setCpu(String cpu) { this.cpu = cpu; }
public void setMemory(String memory) { this.memory = memory; }
public void setStorage(String storage) { this.storage = storage; }
public void setGraphics(String graphics) { this.graphics = graphics; }
public void show() {
System.out.println("CPU: " + cpu + ", 内存: " + memory +
", 存储: " + storage + ", 显卡: " + graphics);
}
}
// 抽象建造者
abstract class ComputerBuilder {
protected Computer computer = new Computer();
public abstract void buildCpu();
public abstract void buildMemory();
public abstract void buildStorage();
public abstract void buildGraphics();
public Computer getResult() {
return computer;
}
}
// 具体建造者
class GamingComputerBuilder extends ComputerBuilder {
public void buildCpu() {
computer.setCpu("Intel i9-12900K");
}
public void buildMemory() {
computer.setMemory("32GB DDR4");
}
public void buildStorage() {
computer.setStorage("1TB NVMe SSD");
}
public void buildGraphics() {
computer.setGraphics("RTX 4080");
}
}
class OfficeComputerBuilder extends ComputerBuilder {
public void buildCpu() {
computer.setCpu("Intel i5-12400");
}
public void buildMemory() {
computer.setMemory("16GB DDR4");
}
public void buildStorage() {
computer.setStorage("512GB SSD");
}
public void buildGraphics() {
computer.setGraphics("集成显卡");
}
}
// 指挥者
class ComputerDirector {
public Computer construct(ComputerBuilder builder) {
builder.buildCpu();
builder.buildMemory();
builder.buildStorage();
builder.buildGraphics();
return builder.getResult();
}
}应用场景
- SQL查询语句构建
- 配置文件生成
- 复杂对象的创建(如汽车、房屋)
🔄 5. 原型模式 (Prototype)
模式意图
用原型实例指定创建对象的种类,通过复制这些原型创建新对象。
结构图
Client Prototype
┌─────────────────┐ ┌─────────────────┐
│ │───►│ + clone() │
└─────────────────┘ └─────────────────┘
△
│
┌─────────────────┐
│ ConcretePrototype│
├─────────────────┤
│ + clone() │
└─────────────────┘代码实现
java
// 抽象原型
abstract class Prototype implements Cloneable {
public abstract Prototype clone();
}
// 具体原型
class ConcretePrototype extends Prototype {
private String name;
private int age;
public ConcretePrototype(String name, int age) {
this.name = name;
this.age = age;
}
public Prototype clone() {
try {
return (Prototype) super.clone();
} catch (CloneNotSupportedException e) {
return null;
}
}
// getter和setter方法
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
}
// 深拷贝示例
class DeepPrototype implements Cloneable {
private String name;
private List<String> hobbies;
public DeepPrototype(String name) {
this.name = name;
this.hobbies = new ArrayList<>();
}
public DeepPrototype clone() {
try {
DeepPrototype cloned = (DeepPrototype) super.clone();
cloned.hobbies = new ArrayList<>(this.hobbies);
return cloned;
} catch (CloneNotSupportedException e) {
return null;
}
}
}应用场景
- 对象创建成本高(如数据库查询结果)
- 需要大量相似对象
- 避免构造函数的复杂初始化
📊 模式对比
创建型模式比较
| 模式 | 创建方式 | 复杂度 | 灵活性 | 适用场景 |
|---|---|---|---|---|
| 单例 | 限制实例 | 低 | 低 | 全局唯一对象 |
| 工厂方法 | 延迟创建 | 中 | 中 | 创建同类产品 |
| 抽象工厂 | 产品族 | 高 | 高 | 创建产品族 |
| 建造者 | 分步构建 | 高 | 高 | 复杂对象构建 |
| 原型 | 复制创建 | 低 | 中 | 相似对象创建 |
选择指南
- 需要唯一实例 → 单例模式
- 创建同类产品 → 工厂方法模式
- 创建产品族 → 抽象工厂模式
- 复杂对象构建 → 建造者模式
- 复制现有对象 → 原型模式
🧮 练习题
基础题
模式识别
- 数据库连接池应该使用哪种模式?
- GUI组件工厂应该使用哪种模式?
代码分析
- 分析给定代码属于哪种创建型模式
- 指出代码中的角色和职责
提高题
设计题
- 设计一个日志系统,支持文件、数据库、网络三种输出方式
- 设计一个汽车制造系统,支持不同品牌和型号
优化题
- 改进单例模式的线程安全性
- 优化建造者模式的链式调用
答案提示
基础题1:
- 数据库连接池:单例模式(确保唯一实例)
- GUI组件工厂:抽象工厂模式(创建组件族)
💡 实战应用
Spring框架中的应用
- 单例模式:Spring Bean默认是单例
- 工厂模式:BeanFactory创建Bean
- 建造者模式:SqlSessionFactoryBuilder
设计原则
- 开闭原则:对扩展开放,对修改关闭
- 依赖倒置:依赖抽象而不是具体实现
- 单一职责:每个类只负责一个职责
📚 本课小结
- 创建型模式:关注对象创建过程,提供灵活的创建方式
- 五种模式:
- 单例:唯一实例
- 工厂方法:延迟创建
- 抽象工厂:产品族
- 建造者:分步构建
- 原型:复制创建
- 选择依据:根据创建需求和复杂度选择合适模式
💪 课后作业
- 实现所有5种创建型模式的代码
- 分析实际项目中创建型模式的应用
- 设计一个文档处理系统,综合运用多种创建型模式
- 研究Spring框架中创建型模式的使用