文章目录
-
- [1. 引言:简单工厂的问题在哪里?](#1. 引言:简单工厂的问题在哪里?)
- [2. 什么是工厂方法模式](#2. 什么是工厂方法模式)
- [3. 工厂方法模式的角色组成](#3. 工厂方法模式的角色组成)
- [4. 示例场景:日志系统](#4. 示例场景:日志系统)
- [5. 抽象产品](#5. 抽象产品)
- [6. 具体产品实现](#6. 具体产品实现)
- [7. 抽象工厂](#7. 抽象工厂)
- [8. 具体工厂实现](#8. 具体工厂实现)
- [9. 客户端使用方式](#9. 客户端使用方式)
- [10. 与简单工厂的对比](#10. 与简单工厂的对比)
- [11. 工厂方法模式的优点](#11. 工厂方法模式的优点)
- [12. 工厂方法模式的缺点](#12. 工厂方法模式的缺点)
- [13. 适用场景](#13. 适用场景)
- [14. JDK 中的工厂方法模式](#14. JDK 中的工厂方法模式)
- 参考

1. 引言:简单工厂的问题在哪里?
我在上一篇文章中,介绍了简单工厂模式 简单工厂模式介绍-CSDN博客。它通过一个工厂类集中创建对象,确实解决了对象创建与使用耦合的问题。
但它也有一个致命缺陷:
每增加一种产品,就必须修改工厂类。
java
switch (type) {
case "A": return new ProductA();
case "B": return new ProductB();
}
这直接违反了 开闭原则(OCP):
对扩展开放,对修改关闭。
于是,一个更"面向对象"的创建模式出现了 ------ 工厂方法模式。
2. 什么是工厂方法模式
定义(GoF)
定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
一句话理解:
把"选择 new 哪个对象"的权力,从 if-else,交给不同的工厂子类。
如果简单工厂让你频繁改 switch,那你需要工厂方法模式。
3. 工厂方法模式的角色组成
工厂方法模式通常包含四个角色:
- 抽象产品(Product)
定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
- 具体产品(ConcreteProduct)
实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间是多对一的关系。
- 抽象工厂(Factory)
提供了创建产品的接口,它包含多个创建产品的方法,可以创建多个不同等级的产品。
- 具体工厂(ConcreteFactory)
主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。
结构示意:

4. 示例场景:日志系统
假设我们要支持多种日志方式:
- 文件日志
- 数据库日志
5. 抽象产品
java
public interface Logger {
void writeLog(String message);
}
6. 具体产品实现
文件日志
java
public class FileLogger implements Logger {
@Override
public void writeLog(String message) {
System.out.println("写入文件日志:" + message);
}
}
数据库日志
java
public class DatabaseLogger implements Logger {
@Override
public void writeLog(String message) {
System.out.println("写入数据库日志:" + message);
}
}
7. 抽象工厂
java
public interface LoggerFactory {
Logger createLogger();
}
8. 具体工厂实现
文件日志工厂
java
public class FileLoggerFactory implements LoggerFactory {
@Override
public Logger createLogger() {
return new FileLogger();
}
}
数据库日志工厂
java
public class DatabaseLoggerFactory implements LoggerFactory {
@Override
public Logger createLogger() {
return new DatabaseLogger();
}
}
9. 客户端使用方式
java
public class Client {
public static void main(String[] args) {
LoggerFactory factory = new FileLoggerFactory();
Logger logger = factory.createLogger();
logger.writeLog("系统启动");
}
}
客户端此时的特点:
- 不再关心具体产品类
- 只依赖抽象接口
- 更换产品只需更换工厂实现
10. 与简单工厂的对比
| 维度 | 简单工厂 | 工厂方法 |
|---|---|---|
| 是否使用继承 | 否 | 是 |
| 是否违反 OCP | 是 | 否 |
| 工厂数量 | 一个 | 多个 |
| 扩展方式 | 修改工厂 | 新增工厂 |
| 系统复杂度 | 低 | 中 |
11. 工厂方法模式的优点
- 符合开闭原则
- 避免 if-else 判断
- 扩展性强
- 客户端与具体产品解耦
- 更符合面向对象设计
12. 工厂方法模式的缺点
- 类的数量明显增多
- 系统结构更加复杂
- 对小型项目可能"过度设计"
13. 适用场景
适合使用
- 产品类型经常扩展
- 不希望频繁修改已有代码
- 框架级开发
- 日志、消息、解析器等组件
不适合使用
- 产品种类固定
- 系统规模较小
- 追求极简实现的场景
14. JDK 中的工厂方法模式
Collection.iterator()
java
Iterator<E> iterator();
- 不同集合返回不同迭代器
- 调用方不关心具体实现类
这是典型的工厂方法思想。