工厂模式通过封装new调用实现解耦,客户端不感知实例化细节;new可能出现在工厂内部、子类实现或依赖注入容器中,但均被抽象隔离,以提升可替换性与可测试性。

new 关键字在工厂模式中并不直接参与对象创建逻辑,它通常被刻意规避——工厂模式的核心思想正是**用函数或类封装 new 的调用,把实例化过程从客户端代码中抽离出来**。
工厂函数里不显式写 new,但内部可能用到
简单工厂或工厂函数返回对象时,可以返回字面量、调用构造函数(隐含 new),或返回 class 实例(需显式 new)。关键在于:调用方不关心是否用了 new。
- 若工厂返回 { name: 'A' },完全没用 new
- 若工厂内部调用 new Product(),那是工厂自己的实现细节,使用者只调用 createProduct()
- ES6 class 工厂中,new 出现在工厂方法体内,但被封装,例如:return new ConcreteProduct();
抽象工厂和工厂方法模式中,new 被延迟到子类
抽象工厂定义接口,具体工厂由子类实现。此时 new 出现在具体工厂的重写方法中,而非顶层逻辑。
- 父类工厂声明 createButton(),不写 new
- 子类 WindowsFactory 重写该方法,并在里面写 new WindowsButton()
- 客户端始终面向抽象调用,完全不知道 new 发生在哪里
依赖注入 + 工厂时,new 更彻底地消失
现代框架(如 Angular、Spring)常将工厂注册为服务,容器负责调用 new 或复用实例。开发者写的“工厂”可能只是一个配置对象或箭头函数,连 new 的影子都没有。
- 例如:provide: Logger, useFactory: () => new ConsoleLogger()
- 容器决定何时、是否执行这个函数,甚至可能缓存结果、跳过 new
- 业务代码只注入 Logger,对 new 零感知
为什么要绕开显式的 new?
不是 new 有问题,而是硬编码 new 破坏了可替换性和测试性。
- 写 new MySQLConnection() 就锁死了数据库实现
- 换成工厂后,测试时可注入 MockConnection,无需改业务代码
- 运行时根据环境变量切换具体类,new 的目标动态变化











