工厂方法模式(Factory Method Pattern)
1. 概述
工厂方法模式是一种创建型设计模式,它通过定义一个创建对象的接口,但由子类决定实例化哪一个类,使得对象的创建过程延迟到子类中。这个模式的核心思想是将对象的创建与使用分离,以提高系统的灵活性和可扩展性。
2. 适用场景
- 在代码中需要在多个类之间切换,而不希望依赖具体的类。
- 系统中的对象创建需要由子类来决定,而不是在父类中实现。
- 希望增加新的产品类时,不影响已有代码。
3. 结构
- Product(产品接口/抽象类):定义了产品的接口,是所有具体产品的父类。
- ConcreteProduct(具体产品):实现或继承产品接口,表示被创建的具体对象。
- Creator(抽象工厂):声明工厂方法,返回一个产品对象。该方法的返回类型是产品的抽象类型。
- ConcreteCreator(具体工厂):实现工厂方法,返回具体产品的实例。
4. 示例代码
假设我们有一个系统需要处理不同类型的日志记录(如文件日志、数据库日志),可以使用工厂方法模式来创建不同类型的日志记录器。
1. 定义产品接口
// 产品接口
interface Logger {
void log(String message);
}
2. 实现具体产品
// 具体产品:文件日志记录器
class FileLogger implements Logger {
@Override
public void log(String message) {
System.out.println("FileLogger: " + message);
}
}
// 具体产品:数据库日志记录器
class DatabaseLogger implements Logger {
@Override
public void log(String message) {
System.out.println("DatabaseLogger: " + message);
}
}
3. 定义工厂接口
// 工厂接口
abstract class LoggerFactory {
public abstract Logger createLogger();
// 其他可能的操作
public void logMessage(String message) {
Logger logger = createLogger();
logger.log(message);
}
}
4. 实现具体工厂
// 具体工厂:文件日志工厂
class FileLoggerFactory extends LoggerFactory {
@Override
public Logger createLogger() {
return new FileLogger();
}
}
// 具体工厂:数据库日志工厂
class DatabaseLoggerFactory extends LoggerFactory {
@Override
public Logger createLogger() {
return new DatabaseLogger();
}
}
5. 测试代码
public class FactoryMethodDemo {
public static void main(String[] args) {
LoggerFactory fileLoggerFactory = new FileLoggerFactory();
LoggerFactory dbLoggerFactory = new DatabaseLoggerFactory();
// 使用文件日志记录器
fileLoggerFactory.logMessage("Logging to a file");
// 使用数据库日志记录器
dbLoggerFactory.logMessage("Logging to a database");
}
}
6. 运行结果
FileLogger: Logging to a file
DatabaseLogger: Logging to a database
7. 分析
- 解耦创建和使用:工厂方法模式将对象的创建和使用分离开来,客户端只需要知道工厂接口而不需要关心具体实现,增强了系统的灵活性。
- 开放/封闭原则:工厂方法模式遵循开放/封闭原则,当需要新增日志记录器时,只需添加新的具体产品和工厂类,而不需要修改已有代码。
- 灵活性:通过引入工厂类,客户端可以选择使用不同的产品实现,不需要直接依赖具体产品类。
8. 优缺点
-
优点:
- 代码结构清晰,扩展性强。
- 符合单一职责原则和开放/封闭原则。
- 客户端只需要知道工厂接口,不需要知道具体产品类的实现。
-
缺点:
- 增加了类的数量,系统的复杂性会有所增加。
- 每新增一个产品类,都需要相应地增加一个工厂类。