0%

工厂模式

工厂模式(Factory Pattern):对象创建的解耦艺术

工厂模式是创建型设计模式的核心,其核心思想是将对象的创建过程与使用过程分离,通过 “工厂” 统一管理对象创建,降低代码耦合度,提高扩展性。根据抽象程度和适用场景,工厂模式可分为三类:简单工厂模式工厂方法模式抽象工厂模式

简单工厂模式(Simple Factory Pattern)

核心思想

通过一个具体的工厂类,根据输入的参数动态决定创建哪种产品实例(所有产品继承自同一父类或接口)。即 “由工厂根据参数选择产品实现”。

结构组成

  • 产品接口 / 父类:定义所有产品的公共方法。
  • 具体产品:实现产品接口的具体类。
  • 工厂类:包含创建产品的逻辑,根据参数返回不同产品实例。

代码示例

以 “计算器工厂” 为例,根据操作符创建不同运算器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// 1. 产品接口(运算器)
interface Operation {
double calculate(double a, double b);
}

// 2. 具体产品(加法、减法)
class AddOperation implements Operation {
@Override
public double calculate(double a, double b) {
return a + b;
}
}

class SubtractOperation implements Operation {
@Override
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
// 1. 产品接口(文档)
interface Document {
void open();
}

// 2. 具体产品(文本文档、表格文档)
class TextDocument implements Document {
@Override
public void open() {
System.out.println("打开文本文档");
}
}

class SpreadsheetDocument implements Document {
@Override
public void open() {
System.out.println("打开表格文档");
}
}

// 3. 工厂接口(文档工厂)
interface DocumentFactory {
Document createDocument();
}

// 4. 具体工厂(文本工厂、表格工厂)
class TextDocumentFactory implements DocumentFactory {
@Override
public Document createDocument() {
return new TextDocument();
}
}

class SpreadsheetDocumentFactory implements DocumentFactory {
@Override
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”“内存” 等相关组件),而无需指定具体类。即 “工厂不仅创建单个产品,而是创建一整套配套产品”。

抽象工厂模式

结构组成

  • 抽象产品簇:多个相关产品的接口(如CPUMemory)。
  • 具体产品:每个抽象产品的实现(如IntelCPUAMDCPU)。
  • 抽象工厂:声明创建每个抽象产品的方法(如createCPU()createMemory())。
  • 具体工厂:实现抽象工厂,创建一整套具体产品(如IntelFactory创建IntelCPUIntelMemory)。

代码示例

以 “电脑硬件工厂” 为例,创建不同品牌的 CPU 和内存:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// 1. 抽象产品簇(CPU和内存)
interface CPU {
void compute();
}

interface Memory {
void store();
}

// 2. 具体产品(Intel和AMD的CPU、内存)
class IntelCPU implements CPU {
@Override
public void compute() {
System.out.println("Intel CPU 计算中");
}
}

class AMDCPU implements CPU {
@Override
public void compute() {
System.out.println("AMD CPU 计算中");
}
}

class IntelMemory implements Memory {
@Override
public void store() {
System.out.println("Intel 内存 存储中");
}
}

class AMDMemory implements Memory {
@Override
public void store() {
System.out.println("AMD 内存 存储中");
}
}

// 3. 抽象工厂(硬件工厂)
interface HardwareFactory {
CPU createCPU();
Memory createMemory();
}

// 4. 具体工厂(Intel工厂和AMD工厂)
class IntelFactory implements HardwareFactory {
@Override
public CPU createCPU() {
return new IntelCPU();
}
@Override
public Memory createMemory() {
return new IntelMemory();
}
}

class AMDFactory implements HardwareFactory {
@Override
public CPU createCPU() {
return new AMDCPU();
}
@Override
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 组件、硬件套件

总结

工厂模式的核心是解耦对象创建与使用,三种模式各有侧重:

  • 简单工厂模式:适合产品固定、需求简单的场景,实现简单但扩展性差。
  • 工厂方法模式:适合产品可能扩展的场景,通过子类延迟创建,扩展性好但类数量多。
  • 抽象工厂模式:适合需要配套产品的场景,确保产品兼容性但扩展新产品困难

欢迎关注我的其它发布渠道