前言
Spring事务、AOP源码、代理模式以及Java执行流程中,在实例化Bean时,离不开工厂模式。
首先,工厂模式属于创建型设计模式,主要用于对象的创建,隐藏具体实现细节,让客户端代码依赖于抽象而非具体类。工厂模式有三种主要类型:简单工厂、工厂方法和抽象工厂。其中每种工厂模式各有优缺点。
工厂模式的意义在于解耦客户端和具体类,提高代码的扩展性和维护性。
其中本文会详细描述,各个工厂模式的实现原理和结构,简单工厂通过一个工厂类根据参数创建不同对象;工厂方法将创建逻辑延迟到子类;抽象工厂则提供创建一系列相关或依赖对象的接口,而不指定具体类。在下面章节中会给出对应的实现代码,以及区分各个模式之间的优缺点。
以及在实际框架中的应用,Spring框架中的BeanFactory就是工厂模式的典型应用。此外,需要指出工厂模式的优缺点,如增加代码复杂度,但提高灵活性和可维护性。
最后,总结工厂模式的价值,如何帮助代码解耦,符合开闭原则,以及如何根据项目需求选择合适的工厂模式类型。
Java 工厂模式原理详解
工厂模式(Factory Pattern)是一种 创建型设计模式,其核心思想是 将对象的创建与使用分离,通过工厂类统一管理对象的实例化过程,从而降低代码耦合度,提高扩展性和维护性。工厂模式主要分为三种类型:简单工厂模式、工厂方法模式 和 抽象工厂模式。
一、工厂模式的核心思想
- 解耦对象创建
客户端不直接通过new
关键字创建对象,而是通过工厂类获取对象实例,避免直接依赖具体实现类。 - 面向接口编程
客户端代码基于抽象接口(或父类)操作,工厂类负责具体子类的实例化。 - 灵活扩展
新增产品类时,只需扩展工厂逻辑,无需修改客户端代码(符合开闭原则)。
二、三种工厂模式的原理与实现
1. 简单工厂模式(Simple Factory)
- 核心:通过一个工厂类,根据传入的参数动态创建不同产品对象。
- 适用场景:产品类型较少且固定,变化不频繁。
类图结构:
+----------------+ +-----------------+
| Product | <|-----| ConcreteProduct |
+----------------+ +-----------------+
| +use(): void |
+----------------+^|
+----------------+
| SimpleFactory |
+----------------+
| +createProduct()|
+----------------+
代码示例:
// 1. 抽象产品接口
interface Product {void use();
}// 2. 具体产品类
class ConcreteProductA implements Product {public void use() {System.out.println("使用产品A");}
}class ConcreteProductB implements Product {public void use() {System.out.println("使用产品B");}
}// 3. 简单工厂类
class SimpleFactory {public static Product createProduct(String type) {if ("A".equals(type)) {return new ConcreteProductA();} else if ("B".equals(type)) {return new ConcreteProductB();}throw new IllegalArgumentException("未知产品类型");}
}// 4. 客户端调用
public class Client {public static void main(String[] args) {Product product = SimpleFactory.createProduct("A");product.use(); // 输出:使用产品A}
}
优缺点:
- 优点:代码简单,易于理解。
- 缺点:新增产品需修改工厂类,违反开闭原则。
2. 工厂方法模式(Factory Method)
- 核心:定义一个创建对象的抽象方法,由子类决定具体实例化的产品类。
- 适用场景:产品类型较多且可能扩展。
类图结构:
+----------------+ +-----------------+
| Product | <|-----| ConcreteProduct |
+----------------+ +-----------------+
| +use(): void |
+----------------+^|
+----------------+ +---------------------+
| Creator | <|-----| ConcreteCreator |
+----------------+ +---------------------+
| +factoryMethod()| | +factoryMethod() |
+----------------+ +---------------------+
代码示例:
// 1. 抽象产品接口
interface Product {void use();
}// 2. 具体产品类
class ConcreteProductA implements Product {public void use() {System.out.println("使用产品A");}
}class ConcreteProductB implements Product {public void use() {System.out.println("使用产品B");}
}// 3. 抽象工厂类
abstract class Creator {public abstract Product factoryMethod();public void doSomething() {Product product = factoryMethod();product.use();}
}// 4. 具体工厂类
class ConcreteCreatorA extends Creator {public Product factoryMethod() {return new ConcreteProductA();}
}class ConcreteCreatorB extends Creator {public Product factoryMethod() {return new ConcreteProductB();}
}// 5. 客户端调用
public class Client {public static void main(String[] args) {Creator creator = new ConcreteCreatorA();creator.doSomething(); // 输出:使用产品A}
}
优缺点:
- 优点:符合开闭原则,扩展性强。
- 缺点:类数量增加,系统复杂度提高。
3. 抽象工厂模式(Abstract Factory)
- 核心:提供一个接口,用于创建 相关或依赖对象家族,而无需指定具体类。
- 适用场景:需要创建一组相互关联的产品(如不同主题的 UI 组件)。
类图结构:
+----------------+ +-----------------+
| AbstractProduct| <|-----| ConcreteProduct |
+----------------+ +-----------------+
| +use(): void |
+----------------+^|
+----------------+ +---------------------+
| AbstractFactory| <|-----| ConcreteFactory |
+----------------+ +---------------------+
| +createProduct()| | +createProduct() |
+----------------+ +---------------------+
代码示例:
// 1. 抽象产品族接口
interface Button {void render();
}interface TextField {void display();
}// 2. 具体产品族(Windows 风格)
class WindowsButton implements Button {public void render() {System.out.println("渲染 Windows 风格按钮");}
}class WindowsTextField implements TextField {public void display() {System.out.println("显示 Windows 风格文本框");}
}// 3. 具体产品族(MacOS 风格)
class MacOSButton implements Button {public void render() {System.out.println("渲染 MacOS 风格按钮");}
}class MacOSTextField implements TextField {public void display() {System.out.println("显示 MacOS 风格文本框");}
}// 4. 抽象工厂接口
interface GUIFactory {Button createButton();TextField createTextField();
}// 5. 具体工厂类
class WindowsFactory implements GUIFactory {public Button createButton() {return new WindowsButton();}public TextField createTextField() {return new WindowsTextField();}
}class MacOSFactory implements GUIFactory {public Button createButton() {return new MacOSButton();}public TextField createTextField() {return new MacOSTextField();}
}// 6. 客户端调用
public class Client {public static void main(String[] args) {GUIFactory factory = new MacOSFactory();Button button = factory.createButton();TextField textField = factory.createTextField();button.render(); // 输出:渲染 MacOS 风格按钮textField.display(); // 输出:显示 MacOS 风格文本框}
}
优缺点:
- 优点:保证产品族的兼容性,易于切换产品系列。
- 缺点:新增产品族需要修改抽象工厂接口,扩展成本高。
三、工厂模式的应用场景
- 框架设计
- Spring 的
BeanFactory
和ApplicationContext
是工厂模式的典型应用,统一管理 Bean 的创建。
- Spring 的
- 数据库连接
- JDBC 的
DriverManager.getConnection()
通过工厂模式创建数据库连接。
- JDBC 的
- 日志系统
- Log4j 或 SLF4J 通过工厂类创建
Logger
对象。
- Log4j 或 SLF4J 通过工厂类创建
- UI 组件库
- 如 JavaFX 或 Swing 中不同风格控件的创建。
四、工厂模式 vs 其他模式
对比维度 | 工厂模式 | 建造者模式 | 单例模式 |
---|---|---|---|
核心目的 | 解耦对象的创建与使用 | 分步构建复杂对象 | 确保全局唯一实例 |
适用场景 | 创建单一或系列对象 | 创建具有多个组成部分的复杂对象 | 需要全局唯一访问点 |
复杂度 | 低到中 | 高 | 低 |
五、总结
- 简单工厂:适用于产品类型固定,通过参数化创建对象。
- 工厂方法:通过子类化扩展产品类型,符合开闭原则。
- 抽象工厂:适用于创建产品家族,保证产品兼容性。
实际开发建议:
- 优先使用 工厂方法模式 以保持扩展性。
- 在需要兼容性强的产品族时选择 抽象工厂模式。
- 避免滥用工厂模式,简单场景可直接使用
new
创建对象。
示例框架应用:
Spring 的 BeanFactory
是工厂模式的经典实现,通过配置文件或注解定义 Bean,由容器负责实例化和依赖注入,彻底解耦业务代码与对象创建逻辑。