工厂模式
工厂模式(Factory Pattern):对象创建的解耦艺术
工厂模式是创建型设计模式的核心,其核心思想是将对象的创建过程与使用过程分离,通过 “工厂” 统一管理对象创建,降低代码耦合度,提高扩展性。根据抽象程度和适用场景,工厂模式可分为三类:简单工厂模式、工厂方法模式和抽象工厂模式。
简单工厂模式(Simple Factory Pattern)
核心思想
通过一个具体的工厂类,根据输入的参数动态决定创建哪种产品实例(所有产品继承自同一父类或接口)。即 “由工厂根据参数选择产品实现”。
结构组成
- 产品接口 / 父类:定义所有产品的公共方法。
- 具体产品:实现产品接口的具体类。
- 工厂类:包含创建产品的逻辑,根据参数返回不同产品实例。
代码示例
以 “计算器工厂” 为例,根据操作符创建不同运算器:
// 1. 产品接口(运算器)
interface Operation {
double calculate(double a, double b);
}
// 2. 具体产品(加法、减法)
class AddOperation implements Operation {
public double calculate(double a, double b) {
return a + b;
}
}
class SubtractOperation implements Operation {
public double calculate(double a, double b) {
return a - b;
}
}
// 3. 简单工厂类(创建运算器)
class OperationFactory {
// 根据参数选择产品
public static Operation createOperation(String operator) {
switch (operator) {
case "+":
return new AddOperation();
case "-":
return new SubtractOperation();
default:
throw new IllegalArgumentException("不支持的运算符");
}
}
}
// 客户端使用
public class SimpleFactoryDemo {
public static void main(String[] args) {
Operation add = OperationFactory.createOperation("+");
System.out.println(add.calculate(1, 2)); // 3.0
Operation subtract = OperationFactory.createOperation("-");
System.out.println(subtract.calculate(5, 3)); // 2.0
}
}
优缺点
优点
- 解耦创建与使用:客户端无需知道产品创建细节,只需调用工厂。
- 封装性好:产品创建逻辑集中在工厂,便于维护。
缺点
- 违反开闭原则:新增产品时需修改工厂类的
switch逻辑,扩展性差。 - 工厂职责过重:所有产品创建逻辑都在一个工厂类中,复杂度高。
适用场景
- 产品种类少且固定(如简单工具类、配置项)。
- 客户端不需要知道产品创建细节,仅需通过参数选择产品。
工厂方法模式(Factory Method Pattern)
核心思想
定义一个创建对象的接口(工厂接口),将具体产品的创建延迟到其子类(具体工厂)。即 “由子类决定创建哪种产品”,实现 “开放扩展、关闭修改”。

结构组成
- 产品接口:定义产品的公共方法。
- 具体产品:实现产品接口的具体类。
- 工厂接口:声明创建产品的抽象方法。
- 具体工厂:实现工厂接口,负责创建对应的具体产品。
代码示例
以 “文档编辑器” 为例,不同文档类型由不同工厂创建:
// 1. 产品接口(文档)
interface Document {
void open();
}
// 2. 具体产品(文本文档、表格文档)
class TextDocument implements Document {
public void open() {
System.out.println("打开文本文档");
}
}
class SpreadsheetDocument implements Document {
public void open() {
System.out.println("打开表格文档");
}
}
// 3. 工厂接口(文档工厂)
interface DocumentFactory {
Document createDocument();
}
// 4. 具体工厂(文本工厂、表格工厂)
class TextDocumentFactory implements DocumentFactory {
public Document createDocument() {
return new TextDocument();
}
}
class SpreadsheetDocumentFactory implements DocumentFactory {
public Document createDocument() {
return new SpreadsheetDocument();
}
}
// 客户端使用
public class FactoryMethodDemo {
public static void main(String[] args) {
// 选择文本工厂,创建文本文档
DocumentFactory textFactory = new TextDocumentFactory();
Document textDoc = textFactory.createDocument();
textDoc.open(); // 打开文本文档
// 选择表格工厂,创建表格文档
DocumentFactory sheetFactory = new SpreadsheetDocumentFactory();
Document sheetDoc = sheetFactory.createDocument();
sheetDoc.open(); // 打开表格文档
}
}
优缺点
优点
- 符合开闭原则:新增产品时,只需新增对应的具体产品和工厂,无需修改现有代码。
- 职责清晰:每个工厂只负责创建一种产品,避免工厂类逻辑臃肿。
- 客户端与产品解耦:客户端通过工厂接口交互,无需依赖具体产品类。
缺点
- 类数量膨胀:每增加一个产品,需同时新增一个具体产品类和一个具体工厂类。
- 客户端复杂度提高:客户端需知道具体工厂的存在,才能选择合适的工厂创建产品。
适用场景
- 产品种类可能扩展(如插件化系统,支持新增功能模块)。
- 客户端不知道所需产品的具体类型,仅知道对应的工厂(如日志框架,不同日志实现对应不同工厂)。
- 典型应用:JDBC(
DriverManager通过不同驱动工厂创建数据库连接)。
抽象工厂模式(Abstract Factory Pattern)
核心思想
提供一个接口,用于创建一系列相关或相互依赖的产品簇(如 “电脑” 包含 “CPU”“内存” 等相关组件),而无需指定具体类。即 “工厂不仅创建单个产品,而是创建一整套配套产品”。

结构组成
- 抽象产品簇:多个相关产品的接口(如
CPU、Memory)。 - 具体产品:每个抽象产品的实现(如
IntelCPU、AMDCPU)。 - 抽象工厂:声明创建每个抽象产品的方法(如
createCPU()、createMemory())。 - 具体工厂:实现抽象工厂,创建一整套具体产品(如
IntelFactory创建IntelCPU和IntelMemory)。
代码示例
以 “电脑硬件工厂” 为例,创建不同品牌的 CPU 和内存:
// 1. 抽象产品簇(CPU和内存)
interface CPU {
void compute();
}
interface Memory {
void store();
}
// 2. 具体产品(Intel和AMD的CPU、内存)
class IntelCPU implements CPU {
public void compute() {
System.out.println("Intel CPU 计算中");
}
}
class AMDCPU implements CPU {
public void compute() {
System.out.println("AMD CPU 计算中");
}
}
class IntelMemory implements Memory {
public void store() {
System.out.println("Intel 内存 存储中");
}
}
class AMDMemory implements Memory {
public void store() {
System.out.println("AMD 内存 存储中");
}
}
// 3. 抽象工厂(硬件工厂)
interface HardwareFactory {
CPU createCPU();
Memory createMemory();
}
// 4. 具体工厂(Intel工厂和AMD工厂)
class IntelFactory implements HardwareFactory {
public CPU createCPU() {
return new IntelCPU();
}
public Memory createMemory() {
return new IntelMemory();
}
}
class AMDFactory implements HardwareFactory {
public CPU createCPU() {
return new AMDCPU();
}
public Memory createMemory() {
return new AMDMemory();
}
}
// 客户端使用
public class AbstractFactoryDemo {
public static void main(String[] args) {
// 使用Intel工厂,创建Intel系列硬件
HardwareFactory intelFactory = new IntelFactory();
CPU intelCPU = intelFactory.createCPU();
Memory intelMem = intelFactory.createMemory();
intelCPU.compute(); // Intel CPU 计算中
intelMem.store(); // Intel 内存 存储中
// 切换到AMD工厂,创建AMD系列硬件
HardwareFactory amdFactory = new AMDFactory();
CPU amdCPU = amdFactory.createCPU();
Memory amdMem = amdFactory.createMemory();
amdCPU.compute(); // AMD CPU 计算中
amdMem.store(); // AMD 内存 存储中
}
}
优缺点
优点
- 产品簇一致性:确保同一工厂创建的产品相互兼容(如 Intel CPU 和 Intel 内存适配)。
- 便于切换产品簇:客户端只需更换具体工厂,即可切换整套产品(如从 Intel 硬件切换到 AMD)。
- 隔离具体实现:客户端通过抽象工厂和产品接口交互,完全屏蔽具体实现。
缺点
- 扩展新产品困难:新增产品(如 “显卡”)需修改抽象工厂接口及所有具体工厂,违反开闭原则。
- 复杂度高:产品簇和工厂层次多,代码结构较复杂。
适用场景
- 系统需使用多套相关产品(如不同品牌的组件套件、不同风格的 UI 组件)。
- 需确保产品兼容性(如 “Windows 风格按钮” 需与 “Windows 风格输入框” 配套使用)。
- 典型应用:GUI 框架(如 Swing 的
LookAndFeel,不同风格的按钮、文本框由同一工厂创建)。
三种工厂模式的对比
| 维度 | 简单工厂模式 | 工厂方法模式 | 抽象工厂模式 |
|---|---|---|---|
| 核心目标 | 单个产品的创建(参数选择) | 单个产品的创建(子类选择) | 产品簇的创建(配套产品) |
| 工厂类型 | 具体类(非接口) | 接口 + 具体子类 | 接口 + 具体子类 |
| 产品数量 | 单个产品接口的多个实现 | 单个产品接口的多个实现 | 多个相关产品接口的实现 |
| 开闭原则支持 | 不支持(修改工厂类) | 支持(新增工厂和产品) | 部分支持(扩展产品簇困难) |
| 典型应用 | 简单工具类创建 | JDBC 驱动、插件系统 | GUI 组件、硬件套件 |
总结
工厂模式的核心是解耦对象创建与使用,三种模式各有侧重:
- 简单工厂模式:适合产品固定、需求简单的场景,实现简单但扩展性差。
- 工厂方法模式:适合产品可能扩展的场景,通过子类延迟创建,扩展性好但类数量多。
- 抽象工厂模式:适合需要配套产品的场景,确保产品兼容性但扩展新产品困难