在Java软件开发中,创建对象是一个频繁且关键的环节。工厂模式作为一种经典的创建型设计模式,旨在提供一种创建对象的最佳方式,将对象的实例化过程与使用过程分离,从而提升代码的灵活性、可维护性和可扩展性。本文将通过图文结合的方式,深入剖析工厂模式的三种核心形式:简单工厂模式、工厂方法模式和抽象工厂模式,并探讨其设计与实现。
核心思想:简单工厂模式,又称静态工厂方法模式,它定义一个工厂类,根据传入的参数,动态决定创建哪一种产品类的实例。
图文设计:
┌─────────────┐
│ Client │
└──────┬──────┘
│ 请求产品
┌──────▼──────┐
│ SimpleFactory │
│ +createProduct│◄──┐
└──────┬──────┘ │
│ 根据参数创建 │ 产品类型参数
┌──────▼──────┐ │
┌───┤ Product │ │
│ │ +use() │ │
│ └─────────────┘ │
│ ┌─────────────┐ │
└──►│ ProductA │ │
│ +use() │ │
└─────────────┘ │
┌─────────────┐ │
│ ProductB │────┘
│ +use() │
└─────────────┘
角色分析:
- 工厂角色(SimpleFactory):负责实现创建所有实例的内部逻辑,提供一个静态方法供客户端调用。
- 抽象产品角色(Product):定义产品的公共接口。
- 具体产品角色(ProductA/B):实现抽象产品接口的具体类。
优点:客户端无需知道具体产品类名,只需知道参数,实现了责任分离。
缺点:工厂类职责过重,新增产品需要修改工厂类逻辑,违反开闭原则。
核心思想:定义一个用于创建对象的接口,但让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
图文设计:
┌─────────────┐ ┌─────────────┐
│ Client ├───────►│ Factory │
└─────────────┘ │+createProduct│
└──────┬──────┘
│
┌──────────────┴──────────────┐
│ │
┌──────▼──────┐ ┌──────▼──────┐
│FactoryA │ │FactoryB │
│+createProduct│ │+createProduct│
└──────┬──────┘ └──────┬──────┘
│ │
┌──────▼──────┐ ┌──────▼──────┐
│ ProductA │ │ ProductB │
│ +use() │ │ +use() │
└─────────────┘ └─────────────┘
角色分析:
- 抽象工厂(Factory):声明工厂方法,返回一个产品类型对象。
- 具体工厂(FactoryA/B):实现工厂方法,返回具体产品实例。
- 抽象产品(Product):定义产品接口。
- 具体产品(ProductA/B):实现产品接口。
优点:完全符合开闭原则,新增产品只需新增对应工厂类,无需修改已有代码。
缺点:每增加一个产品,就需要增加一个具体工厂类,导致类数量增多,系统复杂度增加。
核心思想:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。它强调的是“产品族”的概念。
图文设计:
┌─────────────┐
│ Client │
└──────┬──────┘
│ 使用工厂创建产品族
┌──────▼──────┐
│AbstractFactory│
│+createProductA│
│+createProductB│
└──────┬──────┘
│
┌──────────┴──────────┐
│ │
┌───▼──────┐ ┌──────▼────┐
│Factory1 │ │Factory2 │
│+createA()│ │+createA() │
│+createB()│ │+createB() │
└───┬──────┘ └──────┬────┘
│ │
│ ┌──────────┐ │ ┌──────────┐
└──►│ProductA1 │ └──►│ProductA2 │
└──────────┘ └──────────┘
│ ┌──────────┐ │ ┌──────────┐
└──►│ProductB1 │ └──►│ProductB2 │
└──────────┘ └──────────┘
角色分析:
- 抽象工厂(AbstractFactory):声明一组创建一族产品的方法。
- 具体工厂(Factory1/2):实现抽象工厂的方法,生成一族具体产品。
- 抽象产品(ProductA/B):为每种产品声明接口。
- 具体产品(ProductA1/B1, A2/B2):定义具体工厂生产的特定产品。
应用场景:例如,一个GUI库需要为不同操作系统(如Windows, Mac)提供一套风格一致的按钮(Button)、文本框(Text)等控件。抽象工厂能确保同一工厂生产的产品(如WindowsButton和WindowsText)是兼容的。
优点:保证了客户端始终只使用同一个产品族中的对象,方便切换整个产品族。
缺点:产品族扩展困难(例如新增一个产品类型C,需要修改所有工厂接口和类),且系统结构复杂。
| 模式 | 核心目标 | 复杂度 | 符合开闭原则 | 适用场景 |
| :--- | :--- | :--- | :--- | :--- |
| 简单工厂 | 将对象创建逻辑集中管理 | 低 | 工厂类不符合 | 产品类型较少,且不频繁变化 |
| 工厂方法 | 将具体产品的创建延迟到子类 | 中 | 完全符合 | 不关心具体产品类,但关心产品系列如何被创建 |
| 抽象工厂 | 创建相关或依赖的产品族 | 高 | 产品族符合,产品等级不符合 | 需要创建一系列相关的产品对象 |
设计制作建议:
1. 从简单开始:如果系统简单,产品类型固定,优先考虑简单工厂。
2. 拥抱扩展:当预计未来产品类型会频繁增加时,应采用工厂方法模式。
3. 关注整体:当需要确保一系列相关产品一起工作时,抽象工厂是首选。
4. 图文辅助:在设计时,绘制上述UML类图或示意图,能清晰展示角色关系和创建流程,是沟通和理解的强大工具。
通过合理运用这三种工厂模式,开发者可以构建出松耦合、高内聚且易于维护的Java应用程序架构。
如若转载,请注明出处:http://www.dwbcyv.com/product/58.html
更新时间:2026-03-01 04:47:30