前端进阶之旅前端进阶之旅
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
首页程序员面试题库工厂模式 简单工厂 工厂方法 抽象工厂 区别
设计设计模式可维护代码

简单工厂、工厂方法与抽象工厂三种工厂模式分别解决什么创建问题?

三类工厂按“创建责任下放”的程度分级:简单工厂靠条件分支定类型;工厂方法让子类决定实例;抽象工厂可生成一族配套对象,调用方始终不碰具体创建。

前端进阶之旅 · 一题精讲更新于 2026.09.05
设计模式#可维护代码
先看核心答案
理解线索

按变化点选模式

  1. 简单工厂按参数在单个函数内分支返回对象
  2. 工厂方法定义创建接口,子类决定是哪个实现
  3. 抽象工厂成组提供方法,产品间相配才能共存

只有一个产品维度用工厂方法;变化围绕产品族搭配时才升级到抽象工厂。

核心回答

先记住这个答案

简单工厂用一个入口函数按参数拼出具体对象,适合种类少且稳定的阶段;需要给同一产品加变体时改为工厂方法,让子类覆盖创建方法而不再修改公共代码;当有多个关联产品需要组合使用时,抽象工厂提供一组创建接口,确保客户端取到的产品出自同一族。三者的耦合程度由方法内判断、子类覆盖和族级接口逐级加强。选择时先问变化是单产品品种,还是整套互相依赖的搭配。

  • 简单工厂集中分支,新增类型需要改中心函数
  • 工厂方法把创建选择下放给子类覆盖
  • 抽象工厂管一簇产品,客户端选工厂不选产品

创建责任从中心走向分布

简单工厂用一个函数按参数返回具体实例,将所有分支集中到一处,让调用方避开具体类,但新增类型仍需修改工厂的中心逻辑。工厂方法则把创建方法声明在抽象工厂接口中,让子类覆盖并返回由它决定的对象,父类不关心具体是哪个类,因此新增产品可以在不改动老代码的情况下由新子类加入。两者差别从“改 if 分支”转移到“新增子类”。

从工厂方法到抽象工厂不是复杂度的提升,而是产品数量的维度扩张。一种产品需要多种实现时,工厂方法足够;当发货套餐同时包含箱子、面单和包装且三者必须彼此匹配时,抽象工厂拿出多个 create 方法,分别产生族内对应的产品对象。调用方只面对某个具体工厂,不需要自己挑选产品,就可以保证三个产出之间无跨族搭配。

仓库从单仓扩展成区域发货体系的实例

一个国际仓配系统初始只要按温度创建普通纸箱或冷藏箱,一个 createBox(type) 函数的简单工厂足以满足,新增温度类型也只是加一个分支。两个月后公司要跑美国东岸和欧洲两条专线,两地对包装箱尺寸、外保护层和面单规定都不同,每次发货需要这三样配套,简单工厂如果继续做会同时接收“区域+温度”两维参数,并手工保证三样对象来自同一区域,极易串线。

从这刻起把工厂调整为抽象工厂:定义 LogisticsFactory,上面有关联的 createCarton、createWrapper、createLabel。美国东岸与欧洲分别用一个工厂实现一整套;客户端只要从配置取区域工厂,连续调用三个方法即可完成发货前组装。没过多久加日本仓时,团队新增 JapanFactory,没有碰原有创建渠道,原来核心发货代码保持一致,这正是顺着“产品族”的变化轴选择合适层级的直接结果。

三种款式各自的失效范围

简单工厂在类型到达六七种且构造参数开始变化时变得不可控,因为中心分支很难再做组合判断,任何扩展都可能漏掉某个调用分支,这时就该考虑把“实例化谁”这个动作下沉到工厂子类。继续硬撑简单工厂只会降低可读性,也无法利用多态替换。

工厂方法的风险是类数目泡沫:每个产品配一个工厂子类,若实际产品数目不多而只是接口不同,这种额外的继承维度会让修改路径过长,维护成本反超收益。抽象工厂则要求对象间确实存在强关联和使用协作性;如果一组随机对象被强行组织成“族”,各自独立变化却永远在同一工厂里返回,本质上只是复杂版的工厂方法,并不会带来一致性收益。JavaScript 没有编译期接口,所以这些模式落实时还得依靠命名约定、测试或类型标注来守住边界。

回答前,多想一步

容易答错的地方

简单工厂被扣反模式帽
它不是四人组定义的正式模式,却能充当重构起点。真正失控的并非简单工厂,而是类型无限增多又拒绝演进。它应是过渡方案,不需要一上来就套抽象工厂。
工厂方法和抽象工厂混为一谈
两者都通过工厂接口让调用方避开直接实例,但工厂方法反馈单一产品,抽象工厂回答产品族的整套创建。用抽象工厂处理单维度差异会产生大量无意义方法,扩展一次要写一套无关对象。
试着用自己的话回答

面试官还会怎么问?

新增一个具体类型时应如何判断该走哪种工厂?

先看变化是否属于一个产品:单产品变化只要工厂方法;若它还牵出一组相关规格(标签、包装、面单)就升级到抽象工厂。若类型数固定少于 5 且无明显套餐,可使用简单工厂保持可读。

JavaScript 没有接口,抽象工厂模式怎么落地?

一个工厂不需要 extends,只要它携带 createA、createB 等方法且调用者只用这些方法就成,实际产品一致性仍需人工保证。可用函数返回具名对象,并配合单元测试校验同一次引用所产生的产品是否同签名。

抽象工厂与建造器(构建器)模式能否混用?

可以,当族中各产品还需要复杂组装时,抽象工厂决定哪个族,具体的逐件装配交给 Builder 控制。不要把 Builder 放进抽象工厂接口中,否则会混合创建与表征两个变化点。

从一道题,走向一组知识

把知识连起来

可维护代码

什么信号表明一段对象创建逻辑应该收敛为工厂而不是散落在各处 new?

同属「可维护代码」专题,接着看 工厂模式 何时使用 对象创建 在具体场景中的处理方式。

可维护代码

观察者模式与发布订阅模式在耦合方式上的核心区别是什么?

同属「可维护代码」专题,接着看 观察者模式 发布订阅 区别 在具体场景中的处理方式。

参考资料

  • Functions

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 创建责任从中心走向分布
  3. 仓库从单仓扩展成区域发货体系的实例
  4. 三种款式各自的失效范围
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑