Skip to content
难度基础(★)
建议时长45分钟

10.5.2 创建型设计模式

创建型模式解决“对象如何创建”的问题。它们把创建逻辑从使用者手里拿出来,使客户程序不必依赖具体类,也不必了解复杂构造细节。

创建型共有 5 种:抽象工厂、工厂方法、建造者、原型、单例。

总览表

中文名英文名一句话意图题干关键词
抽象工厂Abstract Factory创建一系列相关或相互依赖的对象,不指定具体类产品族、一系列相关产品、联合使用
工厂方法Factory Method定义创建对象接口,让子类决定实例化哪个类子类决定、延迟实例化、一个产品
建造者/生成器Builder将复杂对象的构建过程与表示分离复杂对象、分步骤构建、同样过程不同表示
原型Prototype通过复制已有原型对象创建新对象克隆、复制、减少实例化开销
单例Singleton保证一个类只有一个实例,并提供全局访问点唯一实例、全局访问点

抽象工厂:生产一族相关产品

抽象工厂提供一个接口,用来创建一系列相关或相互依赖的对象,而不需要指定具体类。

适合场景:系统要支持多个产品系列,并且同一系列产品需要一起使用。例如数据库访问层中,不同数据库都有连接、命令、结果集等一组对象。选择 Oracle 系列时,应创建 OracleConnection、OracleCommand;选择 MySQL 系列时,应创建 MySQLConnection、MySQLCommand。

mermaid
classDiagram
  class AbstractFactory {
    +createProductA()
    +createProductB()
  }
  class Factory1
  class Factory2
  class ProductA
  class ProductB
  class ProductA1
  class ProductA2
  class ProductB1
  class ProductB2
  AbstractFactory <|.. Factory1
  AbstractFactory <|.. Factory2
  ProductA <|.. ProductA1
  ProductA <|.. ProductA2
  ProductB <|.. ProductB1
  ProductB <|.. ProductB2
  Factory1 ..> ProductA1
  Factory1 ..> ProductB1
  Factory2 ..> ProductA2
  Factory2 ..> ProductB2

与工厂方法相比,抽象工厂强调“产品族”,不是只生产一个产品。

工厂方法:把实例化推迟到子类

工厂方法定义一个创建对象的接口,但由具体子类决定实例化哪个类。它的关键句是:让子类决定实例化哪个类,将实例化推迟到子类。

mermaid
classDiagram
  class Creator {
    +factoryMethod()
  }
  class ConcreteCreatorA
  class ConcreteCreatorB
  class Product
  class ConcreteProductA
  class ConcreteProductB
  Creator <|-- ConcreteCreatorA
  Creator <|-- ConcreteCreatorB
  Product <|.. ConcreteProductA
  Product <|.. ConcreteProductB
  ConcreteCreatorA ..> ConcreteProductA
  ConcreteCreatorB ..> ConcreteProductB

考试区分点:

对比项工厂方法抽象工厂
创建对象数量通常返回一个产品创建一族相关产品
变化点具体产品由子类决定产品系列整体切换
关键词子类决定、延迟实例化产品族、一系列、联合使用

建造者:复杂对象的过程与表示分离

建造者也叫生成器。它将复杂对象的构建过程和对象表示分离,使同样的构建过程可以创建不同表示。

课程例子是套餐制作:主餐、饮料、玩具等部件的制作流程相似,但不同套餐的具体表示不同。服务员可以调度厨师按步骤制作套餐,这里的“服务员”对应 Director,“厨师/生成器”对应 Builder。

mermaid
classDiagram
  class Director {
    +construct()
  }
  class Builder {
    +buildPartA()
    +buildPartB()
    +getResult()
  }
  class ConcreteBuilder
  class Product
  Director --> Builder : uses
  Builder <|.. ConcreteBuilder
  ConcreteBuilder --> Product : builds

建造者题目常出现:

  • 复杂对象由多个部分组成。
  • 构建过程相同,但产品表示不同。
  • 需要把构建步骤抽象出来。
  • 类图中有 BuilderDirectorbuildPart()getResult()

原型:通过克隆已有对象创建

原型模式通过复制已有实例来创建新对象,又叫克隆模式。

适合场景:对象创建成本较高,或者对象状态组合有限,可以先保存原型,再复制并按需要微调。它的关键词是 clone、复制、拷贝、减少实例化开销。

mermaid
classDiagram
  class Prototype {
    +clone()
  }
  class ConcretePrototype
  class Client
  Prototype <|.. ConcretePrototype
  Client ..> Prototype : clone()

注意:原型不是“完全不用初始化”,而是用复制替代从头创建;如果新对象和原型有差异,还要修改差异部分。

单例:唯一实例与全局访问点

单例模式保证一个类只有一个实例,并提供访问它的全局访问点。

典型实现会包含静态实例、私有构造方法、静态访问方法。考试不常要求写完整代码,但会考“唯一实例”“全局访问点”。

mermaid
classDiagram
  class Singleton {
    -static instance
    -Singleton()
    +static getInstance()
  }

单例的好处是控制实例数量,避免多个对象产生冲突;代价是全局状态可能增加测试和扩展难度。现代设计中会更谨慎使用单例,很多场景会改用依赖注入管理生命周期。

创建型模式辨析

题干描述应选模式排除思路
一个类仅有一个实例单例不是建造者,也不是原型
复杂对象的构建与表示分离建造者不是抽象工厂,抽象工厂重点是产品族
子类指定创建的对象工厂方法不是抽象工厂,工厂方法通常返回一个产品
一系列相关产品需要联合使用抽象工厂不是工厂方法
通过复制已有实例创建对象原型不是单例,原型可以有多个复制对象

例题

单选
适合将复杂对象的构建与表示分离,使同样的构建过程可以创建不同表示的是:
单选
系统需要创建一系列相关产品,并且这些产品需要联合使用,最适合使用:

自查要点

  1. 抽象工厂和工厂方法的核心区别是什么?
  2. 建造者模式中的 Director 和 Builder 分别负责什么?
  3. 原型模式为什么能减少创建开销?
  4. 单例模式为什么既有用,也容易带来全局状态问题?