简单工厂模式 (Factory)_使用面向对象思维创建对象

星宇吖_8120

星宇吖_8120

2026-02-12

360人浏览

原创

工厂函数将对象创建逻辑集中封装,使调用方只关注“要什么”而非“怎么造”,避免硬编码散落、修改分散及空值风险,应抛异常而非返回null,推荐纯函数实现而非class封装。

简单工厂模式 (factory)_使用面向对象思维创建对象

为什么 new 之后还要再包一层工厂函数

直接 new 类没问题,但一旦构造逻辑变复杂(比如要根据配置选不同子类、要预设默认参数、要统一初始化流程),硬编码就容易散落在各处。工厂函数本质是把“怎么造对象”这个决策收口——不是为了炫技,而是让调用方只关心“我要什么”,不操心“怎么造”。

常见错误现象:if-else 判断塞在业务代码里,新增一种类型就得改多处;或者所有地方都写 new ConcreteA(),结果某天 ConcreteA 需要加参数,全项目搜着改。

  • 使用场景:对象创建依赖外部配置(如读取 JSON 决定实例化哪个类)、需要隐藏具体实现类名、构造过程含副作用(如注册监听、加载资源)
  • 参数差异:工厂函数通常接收一个标识符(如字符串 type 或配置对象),而不是原始构造参数;真正传给构造器的参数应由工厂内部处理或透传
  • 性能影响极小,但要注意别在工厂里做重操作(如同步读文件、网络请求),否则每次 create() 都卡

Factory.create() 返回 null 还是抛异常

返回 null 是最危险的默认选择——调用方很容易忘记判空,接着就 Cannot read property 'xxx' of null。简单工厂不该替调用方做“容错”,它该明确表达“你问了个不存在的东西”。

典型错误:工厂里写 if (type === 'A') return new A(); else return null;,然后业务层直接 factory.create('B').doSomething(),运行时报错才回头找。

  • 建议统一抛 Error,消息里带具体 type 和可用选项,比如 throw new Error(`Unknown type: ${type}. Available: A, B, C`)
  • 如果确实需要“可选创建”,那就显式命名,比如 tryCreate(),并文档注明可能返回 null 或 undefined
  • TypeScript 用户注意:返回类型别写成 MyClass | null,除非真有合法的 null 场景;更推荐用联合类型 + 明确枚举值约束输入

JavaScript 里要不要用 class 实现 Factory

不用。简单工厂的核心是函数,不是类。写成 class Factory { static create() { ... } } 纯属画蛇添足——没有实例状态、不需继承、不靠 this 绑定,加个 class 只会让调用多敲两个点:Factory.create() 对比 create(),还容易让人误以为能 new 出来个工厂实例。

Anylang.ai
Anylang.ai

Anylang.ai是一款AI文本写作工具,AI视频翻译并保持音色和口型的同步。

下载

容易踩的坑:有人把工厂做成单例类,然后在构造器里初始化一堆缓存或连接,结果发现根本没被复用,因为每次都是 new Factory().create(),缓存形同虚设。

  • 直接导出纯函数,例如 export function createService(type, options)
  • 如果真需要封装状态(如共享缓存、配置上下文),用闭包或依赖注入,而不是靠 class 包一层
  • Node.js 环境下注意模块缓存:函数导出后多次 require 拿到的是同一个函数引用,闭包变量天然复用

和依赖注入容器(如 InversifyJS)有什么区别

简单工厂就是手动写的、硬编码的、无反射能力的依赖注入。它不扫描类装饰器、不解析构造函数参数、不管理生命周期。当你还没到需要自动装配几十个服务的程度,或者项目是纯前端小工具,上 DI 容器反而增加心智负担和打包体积。

真实冲突点常出现在团队协作中:有人坚持“所有 new 都得走工厂”,结果连 new Date()、new Map() 都包一层 DateFactory.create(),完全背离初衷。

  • 工厂只管“有业务含义的对象”,比如 PaymentProcessor、NotificationChannel;基础类型、数据结构、纯工具类别裹
  • DI 容器适合大型应用,且要求严格约定(如接口抽象、装饰器标记);简单工厂适合快速验证、脚本、CLI 工具等轻量场景
  • 两者不互斥:可以用工厂作为 DI 容器的“自定义 provider”,但别把工厂当容器用

最常被忽略的一点:工厂函数本身也是依赖。它不该自己读配置、连数据库——这些应该通过参数传入,否则测试时无法 mock,上线后也难切换环境行为。

相关专题

更多
TypeScript工程化开发与Vite构建优化实践
TypeScript工程化开发与Vite构建优化实践

本专题面向前端开发者,深入讲解 TypeScript 类型系统与大型项目结构设计方法,并结合 Vite 构建工具优化前端工程化流程。内容包括模块化设计、类型声明管理、代码分割、热更新原理以及构建性能调优。通过完整项目示例,帮助开发者提升代码可维护性与开发效率。

2026.02.13

312

17

TypeScript全栈项目架构与接口规范设计
TypeScript全栈项目架构与接口规范设计

本专题面向全栈开发者,系统讲解基于 TypeScript 构建前后端统一技术栈的工程化实践。内容涵盖项目分层设计、接口协议规范、类型共享机制、错误码体系设计、接口自动化生成与文档维护方案。通过完整项目示例,帮助开发者构建结构清晰、类型安全、易维护的现代全栈应用架构。

2026.02.25

520

17

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

2026.03.13

391

19

TypeScript 全栈开发进阶指南
TypeScript 全栈开发进阶指南

面向有 JavaScript 基础的开发者,深入讲解 TypeScript 的类型系统与全栈开发实践。

2026.06.03

306

29

TypeScript Node.js 全栈工程化与Monorepo架构实践
TypeScript Node.js 全栈工程化与Monorepo架构实践

本专题围绕 TypeScript 在 Node.js 全栈开发中的工程化实践展开,系统讲解 Monorepo 架构设计、包管理策略、模块复用机制以及服务端与前端统一类型系统的构建方法。通过真实项目案例,帮助开发者提升大型全栈项目的可维护性与协作效率。

2026.06.16

678

8

json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

2023.08.07

2215

5

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.23

3522

1

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

2023.10.13

1176

3

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

2025.09.10

4059

7

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.7万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 134.1万人学习