← 返回题目列表

抽象工厂模式的优缺点是什么?

高频 中等 第 4 / 25 题 更新于 2026/07/28
抽象工厂模式优缺点扩展性开闭原则

简化版

抽象工厂的优点是隔离具体产品类、保证产品族一致性、方便整体切换实现;缺点是结构较重,新增产品等级会牵动所有具体工厂。它适合产品族变化多、产品等级相对稳定的系统。

详细版

主要优点:

  • 调用方依赖抽象产品和抽象工厂,减少对具体类的依赖;
  • 同一具体工厂创建同一产品族,避免产品混搭;
  • 新增产品族时扩展比较自然;
  • 创建逻辑集中在具体工厂,便于替换、测试和配置管理。

主要缺点:

  • 类和接口数量增加,理解成本更高;
  • 新增产品等级要修改抽象工厂和所有具体工厂;
  • 产品族边界设计不好时,工厂接口容易膨胀;
  • 过度使用会让简单对象创建变得绕。

面试回答要结合适用条件,不要只说“解耦、符合开闭原则”。抽象工厂只是在新增产品族时更符合开闭原则,对新增产品等级并不友好。

完整版教学

一、优点一:隔离具体实现

业务代码只依赖 UIFactoryButtonCheckbox 等抽象,不直接依赖 WindowsButtonMacCheckbox。这让替换整套实现变得更容易。

测试时也可以注入一个 FakeFactory,创建一组测试产品。

二、优点二:保证产品族一致性

抽象工厂最有辨识度的优点就是防止混搭。同一个具体工厂产出的产品天然属于同一族。

这比让调用方分别选择每个产品实现更稳,因为调用方不需要理解每个具体产品之间的兼容关系。

三、缺点一:新增产品等级成本高

一旦抽象工厂接口增加 createMenu(),所有具体工厂都必须跟着改。这一点在产品等级频繁变化时会很痛。

所以抽象工厂的前提是产品等级比较稳定,否则后续维护成本会偏高。

四、缺点二:抽象边界难设计

产品族拆得太细,工厂数量会膨胀;产品族拆得太粗,接口会混乱。抽象工厂的难点不是代码写法,而是边界判断。

工程中要围绕真实变化点抽象,而不是为了套模式硬拆。

五、用三平台两组件量化收益和代价

有 Windows、Mac、Linux 三族和 Button、Checkbox 两个等级时,增加 Linux 只新增一行;增加 Menu 则要改工厂接口并补三套实现。这个 3×2 矩阵清楚展示抽象工厂为何“加族容易、加等级困难”。

          Button      Checkbox
Windows   WinButton    WinCheckbox
Mac       MacButton    MacCheckbox
新增 Linux 行: LinButton + LinCheckbox + LinuxFactory
新增 Menu 列: 修改 UIFactory
Win/Mac/Linux Factory 全部增加 createMenu()
产品族一致性换来列扩展成本

矩阵的每一行是一族兼容产品,每一列是一个产品等级。客户端选择一行对应的具体工厂,再从该工厂取得各列产品;如果允许调用方绕过工厂分别选择每个具体类,产品族一致性的结构性保证就消失了。

六、二维扩展成本与模式边界

评审维度本题结论
产品族不变量客户端从同一 UIFactory 取得的组件风格一致。
新增一行(产品族)增加具体产品一套和具体工厂一个,原接口与旧族稳定。
新增一列(产品等级)接口新增方法并修改 N 个具体工厂,成本随产品族数量增长。
不应由工厂承担组件渲染流程、页面布局业务和状态同步。
退回更轻方案的条件产品等级频繁变化时拆成独立小工厂或使用组合注册。

抽象工厂对所有变化并非都开放。它刻意固定列集合,以换取整行切换的一致性;如果系统最常发生的是新增列,工厂接口和所有行实现会频繁联动,此时应拆分工厂边界或选择组合方式。

七、落地验收清单

  1. 为每个具体工厂跑同一组契约测试,确认每个创建方法都返回正确产品等级。
  2. 给产品暴露 familyId() 仅用于测试,校验同一工厂创建的所有产品 familyId 一致。
  3. 加入一个假产品族,记录是否只新增一行实现和装配配置,而未修改旧工厂。
  4. 模拟新增一个产品等级,评估抽象接口和全部具体工厂的真实修改成本。
  5. 检查公共产品接口是否出现 AWS、MySQL、Windows 等具体实现词汇。
  6. 检查具体工厂是否只做组装与创建,没有吞入完整业务流程。
  7. 若产品持有连接或线程池,明确由工厂、容器还是调用方负责关闭。
  8. 若运行期按租户切换工厂,验证路由缓存、凭证刷新和租户隔离。

记忆钩子:收益是整行切换,代价是新增一列要补全所有行。

八、常见误区与追问

  • 误区:抽象工厂在所有方向都符合开闭原则。 它主要对新增产品族开放,对新增产品等级不友好。
  • 误区:保证产品族一致性只是一种命名约定。 客户端只持有一个具体工厂时,创建入口从结构上约束了来源。
  • 误区:类数量增加没有成本。 接口、具体产品和具体工厂都会增加理解与测试负担。
  • 追问:最核心优点是什么? 隔离具体类并确保一组相关产品成套创建与整体替换。
  • 追问:最核心缺点是什么? 产品等级集合被固化,新增等级牵动所有具体工厂。
  • 追问:何时不值得使用? 产品少、无混搭风险或产品等级变化远快于产品族时。

九、加强记忆

抽象工厂的优点集中在“成套创建、整体切换”,缺点集中在“新增一类产品很麻烦”。回答优缺点时带上产品族和产品等级,答案就不会空。