深入解析Java中的工厂模式:对象创建的优雅之道
个人名片
🎓作者简介:java领域优质创作者
🌐个人主页:码农阿豪
📞工作室:新空间代码工作室(提供各种软件服务)
💌个人邮箱:[2435024119@qq.com]
📱个人微信:15279484656
🌐个人导航网站:www.forff.top
💡座右铭:总有人要赢。为什么不能是我呢?
- 专栏导航:
码农阿豪系列专栏导航
面试专栏:收集了java相关高频面试题,面试实战总结🍻🎉🖥️
Spring5系列专栏:整理了Spring5重要知识点与实战演练,有案例可直接使用🚀🔧💻
Redis专栏:Redis从零到一学习分享,经验总结,案例实战💐📝💡
全栈系列专栏:海纳百川有容乃大,可能你想要的东西里面都有🤸🌱🚀
目录
深入解析Java中的工厂模式:对象创建的优雅之道
一、工厂模式概述
工厂模式(Factory Pattern)是创建型设计模式中最常用的一种,它提供了一种创建对象的最佳方式。工厂模式的核心思想是将对象的创建与使用分离,客户端无需知道具体对象的创建细节,只需通过工厂获取所需对象。
1.1 模式定义
工厂模式定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
1.2 模式分类
工厂模式主要分为三种类型:
- 简单工厂模式(Simple Factory)
- 工厂方法模式(Factory Method)
- 抽象工厂模式(Abstract Factory)
1.3 模式优点
- 解耦对象创建与使用
- 提高代码的可维护性和可扩展性
- 符合开闭原则(对扩展开放,对修改关闭)
- 降低代码重复率
- 便于统一管理和控制对象创建过程
二、简单工厂模式
2.1 模式结构
简单工厂模式包含以下角色:
- 工厂类(Factory):负责创建具体产品对象
- 抽象产品(Product):定义产品的公共接口
- 具体产品(ConcreteProduct):实现抽象产品接口的具体类
2.2 代码实现
// 抽象产品
public interface Product {
void use();
}
// 具体产品A
public class ConcreteProductA implements Product {
@Override
public void use() {
System.out.println("使用产品A");
}
}
// 具体产品B
public class ConcreteProductB implements Product {
@Override
public void use() {
System.out.println("使用产品B");
}
}
// 简单工厂
public class SimpleFactory {
public static Product createProduct(String type) {
switch (type) {
case "A":
return new ConcreteProductA();
case "B":
return new ConcreteProductB();
default:
throw new IllegalArgumentException("未知产品类型");
}
}
}
// 客户端
public class Client {
public static void main(String[] args) {
Product productA = SimpleFactory.createProduct("A");
productA.use();
Product productB = SimpleFactory.createProduct("B");
productB.use();
}
}
2.3 优缺点分析
优点:
- 客户端与具体产品解耦
- 客户端无需知道具体产品类名
- 实现简单
缺点:
- 工厂类职责过重,违反单一职责原则
- 添加新产品需要修改工厂类,违反开闭原则
- 静态工厂方法无法形成继承等级结构
三、工厂方法模式
3.1 模式结构
工厂方法模式包含以下角色:
- 抽象工厂(Factory):声明工厂方法
- 具体工厂(ConcreteFactory):实现工厂方法,创建具体产品
- 抽象产品(Product):定义产品接口
- 具体产品(ConcreteProduct):实现产品接口
3.2 代码实现
// 抽象产品
public interface Product {
void use();
}
// 具体产品A
public class ConcreteProductA implements Product {
@Override
public void use() {
System.out.println("使用产品A");
}
}
// 具体产品B
public class ConcreteProductB implements Product {
@Override
public void use() {
System.out.println("使用产品B");
}
}
// 抽象工厂
public interface Factory {
Product createProduct();
}
// 具体工厂A
public class ConcreteFactoryA implements Factory {
@Override
public Product createProduct() {
return new ConcreteProductA();
}
}
// 具体工厂B
public class ConcreteFactoryB implements Factory {
@Override
public Product createProduct() {
return new ConcreteProductB();
}
}
// 客户端
public class Client {
public static void main(String[] args) {
Factory factoryA = new ConcreteFactoryA();
Product productA = factoryA.createProduct();
productA.use();
Factory factoryB = new ConcreteFactoryB();
Product productB = factoryB.createProduct();
productB.use();
}
}
3.3 优缺点分析
优点:
- 完全符合开闭原则
- 符合单一职责原则
- 形成平行的工厂等级结构
- 客户端只需知道抽象工厂和抽象产品
缺点:
- 每增加一个产品就要增加一个具体工厂类
- 增加了系统的抽象性和理解难度
四、抽象工厂模式
4.1 模式结构
抽象工厂模式包含以下角色:
- 抽象工厂(AbstractFactory):声明创建一系列产品的方法
- 具体工厂(ConcreteFactory):实现创建具体产品的方法
- 抽象产品(AbstractProduct):为每种产品声明接口
- 具体产品(ConcreteProduct):实现抽象产品接口
4.2 代码实现
// 抽象产品A
public interface ProductA {
void useA();
}
// 具体产品A1
public class ConcreteProductA1 implements ProductA {
@Override
public void useA() {
System.out.println("使用产品A1");
}
}
// 具体产品A2
public class ConcreteProductA2 implements ProductA {
@Override
public void useA() {
System.out.println("使用产品A2");
}
}
// 抽象产品B
public interface ProductB {
void useB();
}
// 具体产品B1
public class ConcreteProductB1 implements ProductB {
@Override
public void useB() {
System.out.println("使用产品B1");
}
}
// 具体产品B2
public class ConcreteProductB2 implements ProductB {
@Override
public void useB() {
System.out.println("使用产品B2");
}
}
// 抽象工厂
public interface AbstractFactory {
ProductA createProductA();
ProductB createProductB();
}
// 具体工厂1
public class ConcreteFactory1 implements AbstractFactory {
@Override
public ProductA createProductA() {
return new ConcreteProductA1();
}
@Override
public ProductB createProductB() {
return new ConcreteProductB1();
}
}
// 具体工厂2
public class ConcreteFactory2 implements AbstractFactory {
@Override
public ProductA createProductA() {
return new ConcreteProductA2();
}
@Override
public ProductB createProductB() {
return new ConcreteProductB2();
}
}
// 客户端
public class Client {
public static void main(String[] args) {
// 使用第一个工厂族
AbstractFactory factory1 = new ConcreteFactory1();
ProductA productA1 = factory1.createProductA();
ProductB productB1 = factory1.createProductB();
productA1.useA();
productB1.useB();
// 使用第二个工厂族
AbstractFactory factory2 = new ConcreteFactory2();
ProductA productA2 = factory2.createProductA();
ProductB productB2 = factory2.createProductB();
productA2.useA();
productB2.useB();
}
}
4.3 优缺点分析
优点:
- 保证客户端始终只使用同一个产品族中的对象
- 产品族内的约束对客户端透明
- 符合开闭原则(增加新的产品族容易)
缺点:
- 难以支持新种类的产品(需要修改抽象工厂接口)
- 系统抽象性增加,理解难度加大
五、工厂模式的应用场景
5.1 简单工厂模式适用场景
- 工厂类负责创建的对象比较少
- 客户端只需要传入参数,不关心对象创建过程
- 需要集中管理对象的创建逻辑
5.2 工厂方法模式适用场景
- 一个类不知道它所需要的对象的类
- 一个类希望由其子类来指定创建的对象
- 需要灵活、可扩展的框架
5.3 抽象工厂模式适用场景
- 系统需要多个产品族,但每次只使用其中某一族产品
- 系统需要提供一个产品类的库,所有产品以同样的接口出现
- 产品族中的对象被设计成一起工作
六、工厂模式在Java中的典型应用
6.1 JDK中的工厂模式
- Collection.iterator():工厂方法模式
- Calendar.getInstance():简单工厂模式
- NumberFormat.getInstance():工厂方法模式
6.2 Spring框架中的工厂模式
- BeanFactory:工厂方法模式
- ApplicationContext:抽象工厂模式
- FactoryBean:特殊的工厂模式实现
七、工厂模式的最佳实践
-
合理选择工厂模式类型:
- 简单工厂:对象创建逻辑简单
- 工厂方法:需要灵活扩展
- 抽象工厂:处理产品族
-
考虑使用静态工厂方法:
public class Product { private Product() {} public static Product create() { return new Product(); } } -
结合单例模式:
public class SingletonFactory { private static final Product INSTANCE = new Product(); public static Product getInstance() { return INSTANCE; } } -
使用依赖注入框架:
- Spring框架的IoC容器本质上是一个超级工厂
-
命名规范:
- 工厂方法通常命名为
createXxx()或getXxx() - 静态工厂方法通常命名为
valueOf()、of()、getInstance()等
- 工厂方法通常命名为
八、工厂模式与其他模式的比较
8.1 工厂方法 vs 抽象工厂
- 工厂方法:创建单一产品,通过子类决定实例化哪个类
- 抽象工厂:创建产品族,通过子类决定实例化哪个产品族
8.2 工厂模式 vs 建造者模式
- 工厂模式:关注创建什么产品
- 建造者模式:关注如何创建复杂对象
8.3 工厂模式 vs 原型模式
- 工厂模式:通过工厂创建新对象
- 原型模式:通过克隆已有对象创建新对象
九、实战案例:日志记录器工厂
9.1 需求分析
我们需要一个日志系统,可以支持多种日志记录方式(文件、数据库、控制台),并且可以方便地扩展新的日志记录方式。
9.2 使用工厂方法模式实现
// 日志记录器接口
public interface Logger {
void log(String message);
}
// 文件日志记录器
public class FileLogger implements Logger {
@Override
public void log(String message) {
System.out.println("文件日志: " + message);
}
}
// 数据库日志记录器
public class DatabaseLogger implements Logger {
@Override
public void log(String message) {
System.out.println("数据库日志: " + message);
}
}
// 控制台日志记录器
public class ConsoleLogger implements Logger {
@Override
public void log(String message) {
System.out.println("控制台日志: " + 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();
}
}
// 控制台日志记录器工厂
public class ConsoleLoggerFactory implements LoggerFactory {
@Override
public Logger createLogger() {
return new ConsoleLogger();
}
}
// 客户端
public class Client {
public static void main(String[] args) {
LoggerFactory factory = new FileLoggerFactory();
Logger logger = factory.createLogger();
logger.log("这是一个测试消息");
// 可以轻松切换日志方式
factory = new DatabaseLoggerFactory();
logger = factory.createLogger();
logger.log("这是一个测试消息");
}
}
9.3 使用抽象工厂模式扩展
如果需要同时支持不同级别的日志记录(如Info、Error),可以使用抽象工厂模式:
// 抽象产品:Info日志
public interface InfoLogger {
void info(String message);
}
// 抽象产品:Error日志
public interface ErrorLogger {
void error(String message);
}
// 抽象工厂
public interface LoggerAbstractFactory {
InfoLogger createInfoLogger();
ErrorLogger createErrorLogger();
}
// 文件日志具体工厂
public class FileLoggerFactory implements LoggerAbstractFactory {
@Override
public InfoLogger createInfoLogger() {
return new FileInfoLogger();
}
@Override
public ErrorLogger createErrorLogger() {
return new FileErrorLogger();
}
}
// 数据库日志具体工厂
public class DatabaseLoggerFactory implements LoggerAbstractFactory {
@Override
public InfoLogger createInfoLogger() {
return new DatabaseInfoLogger();
}
@Override
public ErrorLogger createErrorLogger() {
return new DatabaseErrorLogger();
}
}
// 客户端使用
public class Client {
public static void main(String[] args) {
LoggerAbstractFactory factory = new FileLoggerFactory();
InfoLogger infoLogger = factory.createInfoLogger();
ErrorLogger errorLogger = factory.createErrorLogger();
infoLogger.info("普通信息");
errorLogger.error("错误信息");
// 切换日志方式
factory = new DatabaseLoggerFactory();
infoLogger = factory.createInfoLogger();
errorLogger = factory.createErrorLogger();
infoLogger.info("普通信息");
errorLogger.error("错误信息");
}
}
十、总结
工厂模式是面向对象设计中最重要的模式之一,它通过将对象的创建与使用分离,提高了系统的灵活性和可维护性。三种工厂模式各有适用场景:
- 简单工厂模式:适用于对象创建逻辑简单的场景
- 工厂方法模式:适用于需要灵活扩展的场景
- 抽象工厂模式:适用于产品族的创建
在实际开发中,我们应该根据具体需求选择合适的工厂模式。同时,现代Java开发中,我们可以结合Spring等IoC容器,更优雅地实现工厂模式的功能。
理解并掌握工厂模式,能够帮助我们设计出更加灵活、可扩展的系统架构,是每一位Java开发者必备的技能。


浙公网安备 33010602011771号