创建型-工厂方法模式
2026/1/15大约 2 分钟Java设计模式创建型模式工厂模式Java设计模式面向对象架构设计最佳实践代码优化
概述
工厂方法模式(Factory Method Pattern)定义一个创建对象的接口,让子类决定实例化哪个类。工厂方法使一个类的实例化延迟到其子类。
适用场景
- 客户端不知道它所需要的对象的类
- 客户端希望通过子类来指定创建对象
- 将创建对象的职责委托给多个工厂子类中的某一个
角色组成
- Product(抽象产品):定义产品的接口
- ConcreteProduct(具体产品):实现产品接口
- Creator(抽象工厂):声明工厂方法
- ConcreteCreator(具体工厂):实现工厂方法,返回具体产品
代码实现
1. 定义产品接口
public interface Product {
void use();
}2. 具体产品
public class ConcreteProductA implements Product {
@Override
public void use() {
System.out.println("使用产品A");
}
}
public class ConcreteProductB implements Product {
@Override
public void use() {
System.out.println("使用产品B");
}
}3. 抽象工厂
public abstract class Creator {
// 工厂方法
public abstract Product createProduct();
// 业务方法
public void doSomething() {
Product product = createProduct();
product.use();
}
}4. 具体工厂
public class ConcreteCreatorA extends Creator {
@Override
public Product createProduct() {
return new ConcreteProductA();
}
}
public class ConcreteCreatorB extends Creator {
@Override
public Product createProduct() {
return new ConcreteProductB();
}
}5. 客户端使用
public class Client {
public static void main(String[] args) {
Creator creatorA = new ConcreteCreatorA();
creatorA.doSomething();
Creator creatorB = new ConcreteCreatorB();
creatorB.doSomething();
}
}# 输出
使用产品A
使用产品B类图
实际案例:日志记录器
// 日志接口
public interface Logger {
void log(String message);
}
// 文件日志
public class FileLogger implements Logger {
@Override
public void log(String message) {
System.out.println("[FILE] " + message);
}
}
// 数据库日志
public class DatabaseLogger implements Logger {
@Override
public void log(String message) {
System.out.println("[DB] " + message);
}
}
// 日志工厂接口
public interface LoggerFactory {
Logger createLogger();
}
// 文件日志工厂
public class FileLoggerFactory implements LoggerFactory {
@Override
public Logger createLogger() {
return new FileLogger();
}
}
// 数据库日志工厂
public class DatabaseLoggerFactory implements LoggerFactory {
@Override
public Logger createLogger() {
return new DatabaseLogger();
}
}JDK 中的应用
java.util.Calendar#getInstance()java.text.NumberFormat#getInstance()java.util.ResourceBundle#getBundle()java.nio.charset.Charset#forName()
优缺点
优点:
- 符合开闭原则,扩展性好
- 符合单一职责原则
- 客户端只需知道工厂类
缺点:
- 类的数量增加,增加复杂度
- 增加了系统的抽象性
与简单工厂对比
| 特性 | 简单工厂 | 工厂方法 |
|---|---|---|
| 工厂类 | 一个 | 多个 |
| 扩展性 | 需修改工厂 | 新增工厂类 |
| 开闭原则 | 违反 | 符合 |
| 复杂度 | 低 | 较高 |
