工厂模式(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
| interface Operation { double calculate(double a, double b); }
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; } }
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));
Operation subtract = OperationFactory.createOperation("-"); System.out.println(subtract.calculate(5, 3)); } }
|
优缺点
优点
- 解耦创建与使用:客户端无需知道产品创建细节,只需调用工厂。
- 封装性好:产品创建逻辑集中在工厂,便于维护。
缺点
- 违反开闭原则:新增产品时需修改工厂类的
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
| interface Document { void open(); }
class TextDocument implements Document { @Override public void open() { System.out.println("打开文本文档"); } }
class SpreadsheetDocument implements Document { @Override public void open() { System.out.println("打开表格文档"); } }
interface DocumentFactory { Document createDocument(); }
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”“内存” 等相关组件),而无需指定具体类。即 “工厂不仅创建单个产品,而是创建一整套配套产品”。
![抽象工厂模式]()
结构组成
- 抽象产品簇:多个相关产品的接口(如
CPU、Memory)。
- 具体产品:每个抽象产品的实现(如
IntelCPU、AMDCPU)。
- 抽象工厂:声明创建每个抽象产品的方法(如
createCPU()、createMemory())。
- 具体工厂:实现抽象工厂,创建一整套具体产品(如
IntelFactory创建IntelCPU和IntelMemory)。
代码示例
以 “电脑硬件工厂” 为例,创建不同品牌的 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
| interface CPU { void compute(); }
interface Memory { void store(); }
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 内存 存储中"); } }
interface HardwareFactory { CPU createCPU(); Memory createMemory(); }
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) { HardwareFactory intelFactory = new IntelFactory(); CPU intelCPU = intelFactory.createCPU(); Memory intelMem = intelFactory.createMemory(); intelCPU.compute(); intelMem.store();
HardwareFactory amdFactory = new AMDFactory(); CPU amdCPU = amdFactory.createCPU(); Memory amdMem = amdFactory.createMemory(); amdCPU.compute(); amdMem.store(); } }
|
优缺点
优点
- 产品簇一致性:确保同一工厂创建的产品相互兼容(如 Intel CPU 和 Intel 内存适配)。
- 便于切换产品簇:客户端只需更换具体工厂,即可切换整套产品(如从 Intel 硬件切换到 AMD)。
- 隔离具体实现:客户端通过抽象工厂和产品接口交互,完全屏蔽具体实现。
缺点
- 扩展新产品困难:新增产品(如 “显卡”)需修改抽象工厂接口及所有具体工厂,违反开闭原则。
- 复杂度高:产品簇和工厂层次多,代码结构较复杂。
适用场景
- 系统需使用多套相关产品(如不同品牌的组件套件、不同风格的 UI 组件)。
- 需确保产品兼容性(如 “Windows 风格按钮” 需与 “Windows 风格输入框” 配套使用)。
- 典型应用:GUI 框架(如 Swing 的
LookAndFeel,不同风格的按钮、文本框由同一工厂创建)。
三种工厂模式的对比
| 维度 |
简单工厂模式 |
工厂方法模式 |
抽象工厂模式 |
| 核心目标 |
单个产品的创建(参数选择) |
单个产品的创建(子类选择) |
产品簇的创建(配套产品) |
| 工厂类型 |
具体类(非接口) |
接口 + 具体子类 |
接口 + 具体子类 |
| 产品数量 |
单个产品接口的多个实现 |
单个产品接口的多个实现 |
多个相关产品接口的实现 |
| 开闭原则支持 |
不支持(修改工厂类) |
支持(新增工厂和产品) |
部分支持(扩展产品簇困难) |
| 典型应用 |
简单工具类创建 |
JDBC 驱动、插件系统 |
GUI 组件、硬件套件 |
总结
工厂模式的核心是解耦对象创建与使用,三种模式各有侧重:
- 简单工厂模式:适合产品固定、需求简单的场景,实现简单但扩展性差。
- 工厂方法模式:适合产品可能扩展的场景,通过子类延迟创建,扩展性好但类数量多。
- 抽象工厂模式:适合需要配套产品的场景,确保产品兼容性但扩展新产品困难