抽象工厂平时接触得少,但它是《工厂模式》的升级版——工厂模式管"创建单个产品",抽象工厂管"创建一族配套产品"。这篇讲清它和工厂模式的区别、以及什么时候用。
一、解决什么问题:产品族要配套
工厂模式解决"创建单个产品"(比如一个 Button)。但有时要创建的是一系列相关产品——比如一套 UI 主题,按钮、文本框、下拉框必须配套(Windows 主题配 Windows 按钮,不能混 Mac 按钮)。
抽象工厂就是"创建产品族的工厂",保证一族产品一定配套。
二、核心结构
| 角色 | 是什么 |
|---|---|
| 抽象工厂 | 声明创建产品族的方法(createButton、createTextBox) |
| 具体工厂 | 实现抽象工厂,创建一整套具体产品 |
| 抽象产品 | 产品接口(Button、TextBox) |
| 具体产品 | 产品实现(WindowsButton、MacButton) |
java
// 抽象产品
interface Button { void render(); }
interface TextBox { void render(); }
// 抽象工厂:声明"创建一族产品"的方法
interface UIFactory {
Button createButton();
TextBox createTextBox();
}
// 具体工厂:Windows 工厂,创建 Windows 一族
class WindowsFactory implements UIFactory {
public Button createButton() { return new WindowsButton(); }
public TextBox createTextBox() { return new WindowsTextBox(); }
}
// Mac 工厂:创建 Mac 一族
class MacFactory implements UIFactory {
public Button createButton() { return new MacButton(); }
public TextBox createTextBox() { return new MacTextBox(); }
}
// 使用:换主题 = 换工厂,一整族产品自动配套
UIFactory factory = new WindowsFactory();
Button btn = factory.createButton(); // 一定是 WindowsButton,不会混 Mac
TextBox box = factory.createTextBox(); // 一定是 WindowsTextBox关键:抽象工厂保证"产品族的一致性"——一个工厂创建出来的产品一定配套,Windows 按钮绝不会配 Mac 文本框。
三、和工厂模式的区别
| 维度 | 工厂模式 | 抽象工厂 |
|---|---|---|
| 创建什么 | 单个产品 | 一族相关产品 |
| 关键保证 | 解耦"创建"和"使用" | 额外保证"产品族配套" |
| 例子 | 只造一个 Button | 造 Button + TextBox + 下拉框,必须配套 |
四、实际应用
- JDBC:
Connection.createStatement()就是抽象工厂——不同数据库的Connection返回各自配套的Statement,不会 MySQL 连接配 Oracle 语句 - 跨平台 UI 库:一套代码,切换 Windows/Mac 工厂就切换整套控件
小结
- 抽象工厂创建"产品族",保证一族产品配套
- 换产品族 = 换具体工厂,客户端代码不变
- 和工厂模式区别:工厂管单个,抽象工厂管一族
