抽象工厂模式(Abstract Factory Pattern)学习笔记
🌟 定义
抽象工厂模式属于创建型设计模式,提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。是工厂方法模式的升级版,支持多个产品族的创建。
🎯 适用场景
- 需要创建产品家族(多个关联产品)
- 系统要独立于产品的创建、组合和表示
- 需要确保产品之间的兼容性
- 需要切换不同产品系列
- 产品对象有多个创建约束条件
🔧 模式结构
📐 类图
🛠️ 核心组成
-
AbstractFactory(抽象工厂)
- 声明创建产品族的方法集合
-
ConcreteFactory(具体工厂)
- 实现抽象工厂接口,创建特定产品族的对象
-
AbstractProduct(抽象产品)
- 定义产品接口,多个产品构成产品族
-
ConcreteProduct(具体产品)
- 实现抽象产品接口的具体类
📝 代码示例
跨平台UI组件案例
// 抽象产品:按钮
interface Button {
void render();
}
// 具体产品:Windows按钮
class WindowsButton implements Button {
@Override
public void render() {
System.out.println("渲染Windows风格按钮");
}
}
// 具体产品:MacOS按钮
class MacOSButton implements Button {
@Override
public void render() {
System.out.println("渲染MacOS风格按钮");
}
}
// 抽象产品:文本框
interface TextField {
void input();
}
// 具体产品:Windows文本框
class WindowsTextField implements TextField {
@Override
public void input() {
System.out.println("Windows文本框输入");
}
}
// 具体产品:MacOS文本框
class MacOSTextField implements TextField {
@Override
public void input() {
System.out.println("MacOS文本框输入");
}
}
// 抽象工厂
interface GUIFactory {
Button createButton();
TextField createTextField();
}
// 具体工厂:Windows组件工厂
class WindowsFactory implements GUIFactory {
@Override
public Button createButton() {
return new WindowsButton();
}
@Override
public TextField createTextField() {
return new WindowsTextField();
}
}
// 具体工厂:MacOS组件工厂
class MacOSFactory implements GUIFactory {
@Override
public Button createButton() {
return new MacOSButton();
}
@Override
public TextField createTextField() {
return new MacOSTextField();
}
}
// 客户端代码
public class Application {
private Button button;
private TextField textField;
public Application(GUIFactory factory) {
button = factory.createButton();
textField = factory.createTextField();
}
public void renderUI() {
button.render();
textField.input();
}
public static void main(String[] args) {
// 根据配置选择工厂
GUIFactory factory = getOSFactory();
Application app = new Application(factory);
app.renderUI();
}
private static GUIFactory getOSFactory() {
String osName = System.getProperty("os.name").toLowerCase();
if (osName.contains("win")) {
return new WindowsFactory();
} else {
return new MacOSFactory();
}
}
}
✅ 优点
- 产品族一致性:保证创建的对象相互兼容
- 切换产品族方便:只需更换具体工厂
- 解耦客户端与具体类:客户端只操作抽象接口
- 符合开闭原则(对扩展开放-新增产品族)
- 符合单一职责原则:将产品创建逻辑集中管理
⚠️ 缺点
- 扩展产品等级困难(对修改关闭-新增产品类型)
- 类数量膨胀(n个产品族×m个产品类型=n×m个类)
- 增加系统抽象性(需要先设计好产品结构)
- 需要提前预判产品变化方向
🔄 相关模式对比
模式 | 区别 |
---|---|
工厂方法模式 | 单个产品等级 vs 多个产品等级 |
建造者模式 | 分步构建复杂对象 vs 创建产品家族 |
原型模式 | 克隆现有对象 vs 创建新对象系列 |
💡 实践建议
-
产品族设计原则:
- 同一产品族中的对象需要协同工作
- 不同产品族的对象不应混合使用
-
层次结构管理:
// 使用Map维护工厂实例 public class FactoryProducer { private static Map<String, GUIFactory> factories = new HashMap<>(); static { factories.put("Windows", new WindowsFactory()); factories.put("MacOS", new MacOSFactory()); } public static GUIFactory getFactory(String type) { return factories.get(type); } }
-
扩展策略:
- 新增产品族:添加新工厂+对应产品实现
- 新增产品类型:需要修改所有工厂接口(慎用)
-
组合使用技巧:
// 结合单例模式管理工厂 class MacOSFactory { private static final MacOSFactory INSTANCE = new MacOSFactory(); private MacOSFactory() {} public static MacOSFactory getInstance() { return INSTANCE; } }
🚀 典型应用
-
跨平台UI框架:
- Java AWT/Swing的Peer机制
- Android/iOS跨平台开发
-
数据库访问层:
// 抽象产品:Connection/Statement interface DatabaseFactory { Connection createConnection(); Statement createStatement(); } // 具体产品:MySQL/Oracle实现
-
游戏引擎:
- 不同画风的角色/场景/道具组合
- 不同物理引擎的实现组合
-
企业级中间件:
- 不同消息队列的Connection/Session组合
- 不同云服务的存储/计算组件组合
📌 实现注意事项
-
空对象处理:
// 空产品实现示例 class NullButton implements Button { @Override public void render() { // 无操作实现 } }
-
参数化工厂:
// 通过枚举类型选择产品 enum ThemeType { MATERIAL, FLAT, RETRO } class ThemeFactory { public static GUIFactory getFactory(ThemeType type) { switch(type) { case MATERIAL: return new MaterialFactory(); case FLAT: return new FlatFactory(); default: return new RetroFactory(); } } }
-
组合产品创建:
// 创建关联产品组 interface VehicleFactory { Engine createEngine(); Wheel createWheel(); Light createLight(); } class CarFactory implements VehicleFactory { // 实现各部件创建方法 }
掌握抽象工厂模式的关键在于理解产品族与产品等级的关系,合理运用可以有效管理系统中的对象创建逻辑,特别适合需要保证产品兼容性和需要动态切换产品系列的复杂系统设计。