Java设计模式之创建型模式( 工厂方法模式)介绍与说明
一、定义与核心思想
工厂方法模式(Factory Method Pattern)是一种创建型设计模式,其核心思想是:
- 将对象的创建与使用解耦,通过定义一个创建对象的接口,由子类决定实例化哪一个类。
- 符合开闭原则:新增产品类型时,只需添加新的具体工厂类和具体产品类,无需修改现有代码。
- 延迟实例化:子类负责具体对象的创建逻辑,父类仅声明工厂方法的接口。
例如,物流应用中,不同运输方式(卡车、轮船)的创建逻辑由子类工厂实现,客户端只需调用工厂方法获取运输对象,无需关心具体类型。
二、模式结构
工厂方法模式包含以下四个关键角色:
- 产品(Product)
- 定义所有具体产品类的通用接口或抽象类。
- 示例:
Logger
接口(日志记录器)、Shape
接口(图形组件)。
- 具体产品(Concrete Product)
- 实现产品接口的具体类。
- 示例:
FileLogger
(文件日志)、Circle
(圆形图形)。
- 创建者(Creator)
- 声明工厂方法(抽象方法或默认实现),返回产品对象。
- 示例:
LoggerFactory
抽象类、ShapeFactory
抽象类。
- 具体创建者(Concrete Creator)
- 实现工厂方法,返回具体产品实例。
- 示例:
FileLoggerFactory
(创建文件日志)、CircleFactory
(创建圆形)。
三、优缺点分析
优点
- 解耦:客户端无需直接依赖具体产品类,只需通过工厂接口获取对象。
- 符合开闭原则:新增产品类型时,只需扩展具体工厂和产品类,无需修改现有代码。
- 封装复杂性:创建逻辑集中于工厂类,降低客户端代码的复杂度。
缺点 - 类数量增加:每个具体产品需对应一个工厂类,系统复杂度可能上升。
- 客户端调用复杂:若产品种类多,需管理多个工厂实例,代码可读性可能下降。
四、典型应用场景
- 多平台适配
- 如跨平台UI组件库中,不同操作系统的按钮(Windows、Linux)由具体工厂创建。
- 日志记录系统
- 支持多种日志输出方式(文件、数据库、控制台),通过具体工厂动态选择。
- 支付网关集成
- 实现支付宝、微信支付等不同支付方式的工厂类,统一调用支付接口。
- 物流运输管理
- 支持卡车、轮船等不同运输方式的创建,通过子类工厂实现差异化逻辑。
五、与简单工厂模式的区别
对比项 | 工厂方法模式 | 简单工厂模式 |
---|---|---|
工厂结构 | 多个具体工厂类,每个对应一种产品 | 单一工厂类,通过条件判断创建产品 |
开闭原则 | 符合(扩展新功能无需修改现有代码) | 违背(新增产品需修改工厂类) |
扩展性 | 高(新增产品只需添加工厂和产品类) | 低(工厂类可能成为“过大类”) |
代码解耦 | 更彻底(客户端仅依赖抽象工厂接口) | 较弱(客户端直接调用工厂方法) |
六、Java代码示例
以下是一个日志记录器的工厂方法模式实现:
// 产品接口
public interface Logger {void log(String message);
}
// 具体产品类
public class FileLogger implements Logger {@Overridepublic void log(String message) {System.out.println("File log: " + message);}
}
public class ConsoleLogger implements Logger {@Overridepublic void log(String message) {System.out.println("Console log: " + message);}
}
// 抽象工厂类
public abstract class LoggerFactory {public abstract Logger createLogger();
}
// 具体工厂类
public class FileLoggerFactory extends LoggerFactory {@Overridepublic Logger createLogger() {return new FileLogger();}
}
public class ConsoleLoggerFactory extends LoggerFactory {@Overridepublic Logger createLogger() {return new ConsoleLogger();}
}
// 客户端调用
public class Client {public static void main(String[] args) {LoggerFactory factory = new FileLoggerFactory();Logger logger = factory.createLogger();logger.log("日志记录开始!"); // 输出:File log: 日志记录开始!}
}
七、总结
工厂方法模式通过将对象的创建逻辑封装在子类工厂中,实现了代码的解耦与扩展性。它适用于需要动态支持多种产品类型且符合开闭原则的场景,但需权衡类数量增加带来的复杂度。在实际开发中,可结合抽象工厂模式处理更复杂的“产品族”创建需求。