一、工厂模式的定义与本质

  工厂模式(Factory Pattern)是面向对象编程中最常用的设计模式之一,属于创建型模式。它是一种用工厂方法代替new操作的模式,用于封装和管理对象的创建,使客户端无需关心对象如何创建,只需通过接口获取对象。

本质:将对象的创建过程封装起来,使客户端与对象的创建过程解耦。


二、工厂模式的三种类型

1. 简单工厂模式(Simple Factory Pattern)

  • 又名:静态工厂方法模式
  • 核心:通过一个工厂类根据传入参数动态实例化具体产品类
  • 组成:工厂类、抽象产品接口、具体产品类

优点:实现对象创建与使用的分离
缺点:违反开闭原则,新增产品需修改工厂类

典型应用场景

  • 创建对象较少且客户端不关注创建细节的情况
  • JDK中DateFormat类实例化、BitmapFactory生成Bitmap对象
  • 数据库驱动加载(如JDBC)
// 抽象产品接口
interface Shape {
void draw();
}
// 具体产品
class Circle implements Shape {
@Override
public void draw() {
System.out.println("Inside Circle::draw() method.");
}
}
// 简单工厂
class ShapeFactory {
public Shape getShape(String shapeType) {
if (shapeType == null) {
return null;
}
if (shapeType.equalsIgnoreCase("CIRCLE")) {
return new Circle();
} else if (shapeType.equalsIgnoreCase("RECTANGLE")) {
return new Rectangle();
}
return null;
}
}

2. 工厂方法模式(Factory Method Pattern)

  • 核心:定义一个创建对象的接口,但由子类决定实例化哪个类
  • 组成:抽象工厂、具体工厂、抽象产品、具体产品
  • 优点:符合开闭原则,新增产品只需添加新工厂类
  • 缺点:类数量增加,系统复杂度上升

典型应用场景

  • 需要频繁扩展产品类型的系统
  • 电商平台的商品分类模块
  • 日志框架(不同日志实现)
// 抽象产品
interface Phone {
void showInfo();
}
// 具体产品
class HuaWeiPhone implements Phone {
@Override
public void showInfo() {
System.out.println("华为手机");
}
}
// 抽象工厂
interface PhoneFactory {
Phone getPhone();
}
// 具体工厂
class HuaWeiPhoneFactory implements PhoneFactory {
@Override
public Phone getPhone() {
return new HuaWeiPhone();
}
}

3. 抽象工厂模式(Abstract Factory Pattern)

  • 核心:提供一个接口,用于创建一组相关或依赖的对象
  • 组成:抽象工厂、具体工厂、抽象产品、具体产品
  • 优点:保证产品族的一致性,支持跨平台/跨配置的统一创建
  • 缺点:新增产品族时需修改工厂接口和所有实现类

典型应用场景

  • 需要创建多个关联对象的系统
  • 跨平台UI组件库(Windows vs. macOS)
  • 电商网站的支付方式(支付宝、微信、银联)
// 抽象产品A
interface Coffee {
void make();
}
// 抽象产品B
interface Dessert {
void serve();
}
// 具体工厂
class StarbucksFactory implements CoffeeShopFactory {
public Coffee createCoffee() {
return new Latte();
}
public Dessert createDessert() {
return new Muffin();
}
}

三、工厂模式的优缺点对比

模式类型优点缺点适用场景
简单工厂实现简单,对象创建与使用分离违反开闭原则,新增产品需修改工厂类创建对象较少且客户端不关注创建细节的情况
工厂方法符合开闭原则,新增产品只需添加新工厂类类数量增加,系统复杂度上升需要频繁扩展产品类型的系统
抽象工厂保证产品族的一致性,支持跨平台/跨配置的统一创建新增产品族时需修改工厂接口和所有实现类需要创建多个关联对象的系统

四、工厂模式的实际应用

1. 数据库连接池

在数据库连接池中,工厂模式用于根据配置动态创建不同类型的数据库连接(如MySQL、PostgreSQL),而无需在业务代码中硬编码连接逻辑。

2. Spring框架

Spring框架广泛使用了工厂模式:

  • BeanFactoryApplicationContext是工厂模式的典型应用
  • @Bean注解和FactoryBean接口允许自定义Bean的创建逻辑

3. 日志框架

如Log4j、SLF4J等日志框架使用工厂模式,根据配置动态选择不同的日志实现。

4. SpringBoot自动装配

SpringBoot的自动装配机制本质上也使用了工厂模式的思想,通过@EnableAutoConfigurationAutoConfigurationImportSelector实现自动配置类的动态加载。


五、为什么使用工厂模式

正如知识库中所述:“工厂模式是Java中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。”

使用工厂模式的主要原因:

  1. 避免直接使用new:避免在代码中直接使用new操作符,使代码更加灵活
  2. 降低耦合度:将对象的创建和使用分离,降低类之间的依赖
  3. 提高可扩展性:符合开闭原则,新增产品类型时无需修改现有代码
  4. 集中管理:将对象创建逻辑集中管理,便于维护和修改

六、工厂模式与SpringBoot的结合

在SpringBoot中,工厂模式的应用非常广泛,例如:

  1. Bean的创建:Spring的IoC容器本身就是一种工厂模式,通过BeanFactoryApplicationContext获取Bean实例

  2. 策略模式与工厂模式结合:在策略模式中,可以使用工厂模式来创建具体的策略对象,实现策略的动态切换

  3. 数据库连接:Spring Boot通过DataSource工厂类动态创建不同数据库连接

  4. 自定义Bean:通过FactoryBean接口实现自定义Bean的创建逻辑

// Spring Boot中的自定义FactoryBean
public class CustomBeanFactory implements FactoryBean<CustomBean> {
  @Override
  public CustomBean getObject() throws Exception {
  return new CustomBean();
  }
  @Override
  public Class<?> getObjectType() {
    return CustomBean.class;
    }
    }

七、总结

工厂模式是Java中最重要的设计模式之一,它通过封装对象的创建过程,使代码更加灵活、可维护和可扩展。在实际开发中,应根据具体需求选择合适的工厂模式:

  • 当产品种类较少时,使用简单工厂模式
  • 当需要扩展产品类型时,使用工厂方法模式
  • 当需要创建一组相关对象时,使用抽象工厂模式

正如知识库中所述:"工厂模式是我们最常用的模式了,著名的Jive论坛,就大量使用了工厂模式,工厂模式在Java程序系统可以说是随处可见。"在SpringBoot等现代框架中,工厂模式的应用更加广泛,是构建可扩展、可维护系统的重要基础。

在实际项目中,合理使用工厂模式能有效避免"if…else"条件分支过多的问题,使代码更加清晰、易于维护,符合面向对象设计原则。