工厂方法模式(Factory Method Pattern)学习笔记
🌟 定义
工厂方法模式属于创建型设计模式,定义一个创建对象的接口,但让子类决定实例化哪一个类。将类的实例化操作延迟到子类,是面向对象设计中"开闭原则"的典型体现。
🎯 适用场景
- 需要解耦对象创建与使用
- 无法预知对象确切类型及其依赖关系
- 需要为不同环境提供不同产品实现
- 需要扩展系统时不影响已有代码
- 框架设计(允许用户扩展框架组件)
🔧 模式结构
📐 类图
🛠️ 核心组成
-
Creator(抽象创建者)
- 声明工厂方法(可包含默认实现)
- 通过工厂方法获取产品对象
-
ConcreteCreator(具体创建者)
- 重写工厂方法,返回具体产品实例
-
Product(抽象产品)
- 定义产品接口
-
ConcreteProduct(具体产品)
- 实现抽象产品接口的具体类
📝 代码示例
文档处理系统案例
// 抽象产品:文档
interface Document {
void open();
void save();
void close();
}
// 具体产品:Word文档
class WordDocument implements Document {
@Override
public void open() {
System.out.println("打开Word文档");
}
@Override
public void save() {
System.out.println("保存Word文档");
}
@Override
public void close() {
System.out.println("关闭Word文档");
}
}
// 具体产品:PDF文档
class PDFDocument implements Document {
@Override
public void open() {
System.out.println("打开PDF文档");
}
@Override
public void save() {
System.out.println("保存PDF文档");
}
@Override
public void close() {
System.out.println("关闭PDF文档");
}
}
// 抽象创建者:应用程序
abstract class Application {
// 工厂方法
public abstract Document createDocument();
// 业务方法
public void newDocument() {
Document doc = createDocument();
doc.open();
doc.save();
doc.close();
}
}
// 具体创建者:Word应用
class WordApplication extends Application {
@Override
public Document createDocument() {
return new WordDocument();
}
}
// 具体创建者:PDF应用
class PDFApplication extends Application {
@Override
public Document createDocument() {
return new PDFDocument();
}
}
// 客户端使用
public class Client {
public static void main(String[] args) {
Application app = getApplication();
app.newDocument();
}
private static Application getApplication() {
// 根据配置或环境选择具体创建者
return new WordApplication();
// return new PDFApplication();
}
}
✅ 优点
- 解耦客户端与具体产品类
- 符合开闭原则(新增产品不影响已有代码)
- 支持单一职责原则(创建逻辑集中管理)
- 支持可扩展性(容易添加新产品类型)
- 可作为框架基础(定义扩展点)
⚠️ 缺点
- 需要引入多个新类(增加复杂度)
- 需要继承体系(可能破坏封装性)
- 仅适用于相同产品类型的不同实现
- 需要预先设计工厂层次结构
🔄 相关模式对比
模式 | 区别 |
---|---|
简单工厂 | 静态工厂方法 vs 多态工厂方法 |
抽象工厂 | 创建产品族 vs 创建单个产品 |
模板方法 | 共用算法骨架 vs 创建对象实例 |
💡 实践建议
-
命名规范:
- 工厂方法通常命名为
createXxx()
- 具体产品类使用
产品类型+Product
格式
- 工厂方法通常命名为
-
组合使用技巧:
// 结合单例模式 class DatabaseConnectionFactory { private static final ConnectionFactory instance = new MySQLConnectionFactory(); public static Connection getConnection() { return instance.createConnection(); } }
-
参数化工厂:
enum DocumentType { WORD, PDF, MARKDOWN } class UniversalApplication extends Application { private DocumentType type; public UniversalApplication(DocumentType type) { this.type = type; } @Override public Document createDocument() { switch(type) { case WORD: return new WordDocument(); case PDF: return new PDFDocument(); default: throw new IllegalArgumentException(); } } }
-
依赖注入:
// 通过构造函数注入工厂 class DocumentService { private final DocumentFactory factory; public DocumentService(DocumentFactory factory) { this.factory = factory; } public void processDocument() { Document doc = factory.createDocument(); // 处理文档... } }
🚀 典型应用
-
Java集合框架:
// Iterator工厂方法 List<String> list = new ArrayList<>(); Iterator<String> it = list.iterator(); // 工厂方法
-
Spring框架:
// BeanFactory接口 public interface BeanFactory { Object getBean(String name); }
-
日志框架:
// Logger工厂 Logger logger = LoggerFactory.getLogger(MyClass.class);
-
JDBC驱动:
// DriverManager.getConnection()本质是工厂方法 Connection conn = DriverManager.getConnection(url);
📌 实现注意事项
-
工厂方法可见性:
- 通常声明为
protected
(允许子类重写) - 也可以声明为
public
(直接调用)
- 通常声明为
-
空对象处理:
class NullDocument implements Document { @Override public void open() { /* 无操作 */ } // 其他方法类似 }
-
默认实现策略:
abstract class Application { // 提供默认产品实现 public Document createDocument() { return new DefaultDocument(); } }
-
产品注册机制:
class PluginManager { private static Map<String, PluginFactory> plugins = new HashMap<>(); public static void registerPlugin(String type, PluginFactory factory) { plugins.put(type, factory); } public static Plugin createPlugin(String type) { return plugins.get(type).create(); } }
掌握工厂方法模式的关键在于理解对象创建责任委托的思想,合理使用可以显著提高系统的灵活性和可维护性。当系统需要支持多种同类产品的扩展时,工厂方法模式是最佳选择方案之一。