抽象工厂模式适用于成套创建内在关联对象,需满足多产品等级结构、多产品族及族内一致性三条件;新增产品族易,新增产品等级难。

抽象工厂模式不是为“造一个对象”设计的,而是为“成套创建一组有内在关联的对象”服务的。它真正发力的地方,是当你的系统需要同时支持多个产品族(比如 Windows/Mac/Linux 三套 UI 组件、暗色/浅色/高对比度三套主题、RDB/NoSQL/文件存储三套数据层),且这些组件之间必须风格统一、行为协同时。
明确适用场景:什么情况下该用抽象工厂
别一上来就写工厂接口。先确认是否满足以下三个条件:
- 存在多个产品等级结构:比如既有 Button,又有 Checkbox、TextBox,它们属于同一层级的不同产品类型
- 存在多个产品族:比如 WindowsButton + WindowsCheckbox 是一族,MacButton + MacCheckbox 是另一族,各族内部对象天然适配
- 客户端需隔离具体实现,且要保证族内一致性:不能让 WindowsButton 和 MacCheckbox 混搭使用——抽象工厂天然阻止这种错误
常见误用:只有一种产品类型(如仅需创建不同数据库连接)、或产品间无关联(如日志器和配置加载器混在一个工厂里),这时用简单工厂或工厂方法更合适。
四要素落地:从接口定义到运行时切换
以跨平台 UI 组件库为例,四个角色应这样组织:
-
抽象产品接口:定义每类产品的能力契约,例如
Button接口含render()、onClick();Checkbox含check()、isChecked() -
具体产品类:每个平台实现各自版本,如
WinButton、MacButton、LinuxCheckbox等,只关注自身渲染逻辑 -
抽象工厂接口:声明整套创建能力,如
createButton(): Button、createCheckbox(): Checkbox—— 方法名体现“族”的完整性 -
具体工厂类:如
WinFactory全部返回 Windows 系列组件;MacFactory全部返回 Mac 系列。切换平台只需替换工厂实例,不碰 UI 组件调用代码
运行时动态切换与配置驱动
工厂不该硬编码在业务逻辑里。推荐两种轻量接入方式:
-
环境变量或配置中心驱动:启动时读取
PLATFORM=mac,自动注入MacFactory实例(如通过 DI 容器绑定) -
主题热切换支持:将工厂实例存为单例或上下文对象,UI 设置页点“切暗色模式”时,销毁旧工厂引用,新建
DarkThemeFactory并通知所有组件重绘 - 避免全局状态污染:不要用 static 工厂单例管理多族——改用依赖注入或工厂上下文参数传递,确保测试可隔离、多租户可并行
警惕扩展陷阱:新增平台 or 新增组件?
抽象工厂的优势和短板都集中在这里:
-
加新平台(新产品族)很轻松:新增
LinuxFactory及其全套LinuxButton、LinuxCheckbox即可,不改任何现有代码,符合开闭原则 -
加新组件类型(新产品等级)较麻烦:若要新增
Slider控件,需同步修改抽象工厂接口(加createSlider())、所有具体工厂类、所有抽象/具体产品接口——这是模式固有代价 -
折中建议:对高频迭代的组件(如新交互控件),可预留
createComponent(type: string)泛型方法,配合注册表机制,把部分扩展成本转移到运行时
它不追求万能,而是在“多族强关联”这个明确边界内,把耦合降到最低、把一致性兜住、把扩展路径理清楚。










