抽象工厂模式 (Abstract Factory Pattern)
模式定义
抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。它是工厂方法模式的升级版,用于创建产品族。
核心概念
- 产品族 (Product Family): 由同一个工厂创建的一组相关产品
- 产品等级 (Product Hierarchy): 同一产品的不同实现
实现示例:跨平台 UI
产品接口
java
// 按钮产品接口
public interface Button {
void render();
void onClick(Runnable action);
}
// 文本框产品接口
public interface TextField {
void render();
void setText(String text);
}
// 复选框产品接口
public interface Checkbox {
void render();
void setChecked(boolean checked);
}Windows 产品族
java
// Windows 按钮
public class WindowsButton implements Button {
@Override
public void render() {
System.out.println("渲染 Windows 风格按钮");
}
@Override
public void onClick(Runnable action) {
System.out.println("Windows 按钮点击事件");
action.run();
}
}
// Windows 文本框
public class WindowsTextField implements TextField {
@Override
public void render() {
System.out.println("渲染 Windows 风格文本框");
}
@Override
public void setText(String text) {
System.out.println("Windows 文本框设置内容: " + text);
}
}
// Windows 复选框
public class WindowsCheckbox implements Checkbox {
@Override
public void render() {
System.out.println("渲染 Windows 风格复选框");
}
@Override
public void setChecked(boolean checked) {
System.out.println("Windows 复选框状态: " + (checked ? "选中" : "未选中"));
}
}macOS 产品族
java
// macOS 按钮
public class MacButton implements Button {
@Override
public void render() {
System.out.println("渲染 macOS 风格按钮");
}
@Override
public void onClick(Runnable action) {
System.out.println("macOS 按钮点击事件");
action.run();
}
}
// macOS 文本框
public class MacTextField implements TextField {
@Override
public void render() {
System.out.println("渲染 macOS 风格文本框");
}
@Override
public void setText(String text) {
System.out.println("macOS 文本框设置内容: " + text);
}
}
// macOS 复选框
public class MacCheckbox implements Checkbox {
@Override
public void render() {
System.out.println("渲染 macOS 风格复选框");
}
@Override
public void setChecked(boolean checked) {
System.out.println("macOS 复选框状态: " + (checked ? "选中" : "未选中"));
}
}抽象工厂接口
java
// UI 工厂接口
public interface UIFactory {
Button createButton();
TextField createTextField();
Checkbox createCheckbox();
}具体工厂
java
// Windows UI 工厂
public class WindowsUIFactory implements UIFactory {
@Override
public Button createButton() {
return new WindowsButton();
}
@Override
public TextField createTextField() {
return new WindowsTextField();
}
@Override
public Checkbox createCheckbox() {
return new WindowsCheckbox();
}
}
// macOS UI 工厂
public class MacUIFactory implements UIFactory {
@Override
public Button createButton() {
return new MacButton();
}
@Override
public TextField createTextField() {
return new MacTextField();
}
@Override
public Checkbox createCheckbox() {
return new MacCheckbox();
}
}客户端代码
java
// 表单组件,使用抽象工厂创建 UI 元素
public class Form {
private final Button button;
private final TextField textField;
private final Checkbox checkbox;
public Form(UIFactory factory) {
this.button = factory.createButton();
this.textField = factory.createTextField();
this.checkbox = factory.createCheckbox();
}
public void render() {
System.out.println("=== 渲染表单 ===");
textField.render();
checkbox.render();
button.render();
}
public void submit() {
button.onClick(() -> {
System.out.println("表单提交成功!");
});
}
}
// 测试代码
public class AbstractFactoryDemo {
public static void main(String[] args) {
// 根据操作系统选择工厂
String os = System.getProperty("os.name").toLowerCase();
UIFactory factory;
if (os.contains("win")) {
factory = new WindowsUIFactory();
} else if (os.contains("mac")) {
factory = new MacUIFactory();
} else {
factory = new WindowsUIFactory(); // 默认
}
// 创建表单
Form form = new Form(factory);
form.render();
form.submit();
}
}运行时动态切换工厂
java
// 工厂枚举,支持运行时选择
public enum UIFactoryType {
WINDOWS, MAC
}
// 工厂工厂,根据枚举创建具体工厂
public class UIFactoryCreator {
public static UIFactory createFactory(UIFactoryType type) {
switch (type) {
case WINDOWS:
return new WindowsUIFactory();
case MAC:
return new MacUIFactory();
default:
throw new IllegalArgumentException("不支持的 UI 类型: " + type);
}
}
}
// 使用
UIFactory factory = UIFactoryCreator.createFactory(UIFactoryType.MAC);
Form form = new Form(factory);JDBC 中的抽象工厂
java
// JDBC 连接工厂就是典型的抽象工厂模式
Connection connection = DriverManager.getConnection(url, user, password);
// 不同的 JDBC 驱动实现返回不同的 Connection、Statement、ResultSet 等产品族产品族 vs 产品等级
产品族 按钮 文本框 复选框
Windows WindowsButton WindowsTextField WindowsCheckbox
macOS MacButton MacTextField MacCheckbox
Linux LinuxButton LinuxTextField LinuxCheckbox每一行是一个产品族,每一列是一个产品等级。抽象工厂保证同一工厂创建的产品属于同一产品族。
优缺点
优点:
- 保证同族产品的兼容性
- 符合开闭原则,新增产品族容易
- 隔离具体类,客户端只依赖接口
缺点:
- 新增产品类型困难(需要修改所有工厂接口)
- 类数量多,系统复杂度高
实际应用
- Java GUI: AWT/Swing 的跨平台 UI
- 数据库访问: 不同数据库的 Connection、Statement、ResultSet
- 游戏引擎: 不同平台的渲染、音频、输入设备
- 换肤功能: 不同皮肤主题下的 UI 组件