抽象工厂模式用于统一创建一组内在关联、风格一致的产品对象。它通过产品族(如MacUI族、WinUI族)和产品等级(如Button、TextBox)两个维度组织对象,定义抽象工厂与抽象产品接口,由具体工厂实现“全家桶式”交付,客户端仅依赖抽象接口,运行时可无缝切换产品族。

抽象工厂模式不是用来“创建变量集”的,而是用来统一创建一组有内在关联、风格一致或平台适配的产品对象。所谓“家族特性”,指的是这些对象在业务逻辑、外观行为或运行环境上天然成套——比如 Windows 风格的按钮 + 文本框 + 下拉菜单,或 Apple 生态的 iPhone 屏幕 + iOS 按钮 + AirDrop 组件。关键不在“变量”本身,而在对象之间的契约一致性与可替换性。
明确产品族与产品等级结构
动手前必须厘清两个维度:
- 产品族(Family):横向分组,代表同一主题下的不同组件。例如“MacUI族”包含 MacButton、MacTextBox、MacScrollBar;“WinUI族”对应 WinButton、WinTextBox、WinScrollBar。
- 产品等级(Type):纵向分类,代表同一类功能的不同实现。例如所有 Button 都实现 IButton 接口,所有 TextBox 都实现 ITextBox 接口。
只有同时存在多个族(如 Mac/Win/Linux)和多个等级(Button/TextBox/Menu),抽象工厂才有实际价值。若只有一种族或一种等级,用工厂方法甚至简单工厂更合适。
定义抽象工厂与抽象产品接口
这是整个模式的骨架,决定后续扩展是否平滑:
- 为每个产品等级声明一个抽象产品接口(如 IButton、ITextBox),只暴露公共行为(click()、render()、setFocus()),不涉及实现细节。
- 声明一个抽象工厂接口(如 IGUIFactory),其中每个方法返回一个抽象产品类型,例如 createButton(): IButton、createTextBox(): ITextBox。
- 接口方法命名要体现语义一致性,避免 createWinButton() 这类绑定具体族的名称——那是具体工厂该干的事。
实现具体工厂与具体产品
每个具体工厂负责“全家桶式”交付,确保内部产品天然兼容:
- WinFactory 实现 IGUIFactory,其 createButton() 返回 WinButton 实例,createTextBox() 返回 WinTextBox 实例——二者共享 Windows 消息循环、DPI 缩放逻辑和系统字体栈。
- MacFactory 同理,但所有返回对象都基于 Cocoa 框架、使用 NSButton/ NSTextField,内部协同通过 NSNotificationCenter 或委托机制完成。
- 具体产品类不直接相互引用,而是通过抽象接口协作。例如 WinTextBox 不持有 WinButton 实例,但能接收来自任意 IButton 的 onTextChanged 事件。
客户端只依赖抽象,运行时切换族
客户端代码完全不知道 Win 或 Mac 的存在:
- 构造时注入 IGUIFactory 实例(如 new Application(new WinFactory()) 或 new Application(new MacFactory()))。
- 界面初始化时调用 factory.createButton() 和 factory.createTextBox(),拿到的是抽象类型,但实际是整套匹配的对象。
- 更换风格只需替换工厂实例,无需修改任何 UI 构建逻辑——这对 A/B 测试、主题切换、多端适配极为关键。
不复杂但容易忽略

















