new本身不是设计模式,而是创建型模式的分水岭——所有创建型模式的核心目标是将new调用从客户端剥离并封装:工厂、建造者、抽象工厂等通过可控入口替代散落的new,依托抽象层与多态实现类型解耦,结合单例、原型、对象池控制生命周期,并用new.target等机制加固架构边界。

new 绑定本身不是设计模式,但它在设计模式中扮演关键“分水岭”角色:它标志着对象创建的临界点,而所有创建型模式的核心目标,就是**把 new 的调用从客户端代码里拿走、藏起来、管起来**。
隔离变化,让 new 不再散落各处
直接写 new User() 或 new MySQLConnection(),等于把具体类型和构造细节硬编码进业务逻辑。一旦要换实现(比如改用 PostgreSQL)、加参数(比如传入连接池)、或引入缓存逻辑,就得挨个改调用点。
工厂模式、建造者模式、抽象工厂等,本质都是用一个可控入口替代散落的 new:
- 工厂方法返回
IUser接口,背后可能是LocalUser或OAuthUser,客户端完全不感知 - 建造者用
.build()封装多步初始化,避免构造函数参数爆炸,new 被限制在 build 内部 - 抽象工厂确保
createButton()和createDialog()返回同一 UI 风格下的配套组件,new 只出现在具体工厂内部,且成对出现
支撑多态与抽象,让 new 有据可依
new 的目标类型必须明确——但设计模式要的是“不确定具体类型,却能安全创建”。这靠的是语言机制 + 模式结构的配合:
- 抽象工厂依赖
interface或abstract class声明产品契约,new 只发生在具体子类中,而客户端只依赖抽象层 - 工厂方法让子类决定 new 哪个具体类,父类只定义“我要一个产品”,不关心 new 谁
- TypeScript 中
new () => T类型可以描述构造函数签名,让工厂接收“可被 new 的类型”作为参数,把 new 的能力变成可传递、可约束的值
控制实例生命周期,让 new 不再轻率
有些场景下,不能随便 new:
- 单例模式中,new 只允许发生一次,后续调用必须返回已有实例——new 被封装在 getInstance 的判断逻辑里
- 原型模式用 clone 替代 new,避免重复初始化开销;new 只用于创建初始原型,之后全部克隆
- 对象池模式中,new 被延迟到首次需要时,并复用回收对象,new 的时机和数量由池统一调度
避免误用 new,守住架构边界
像 new.target 这样的机制,虽不构成设计模式,却常被用来加固模式边界:
- 在抽象工厂基类中,用
if (new.target === AbstractFactory)抛错,防止用户直接 new 抽象类 - 在基类构造器中检测
new.target是否为子类,确保只能通过继承扩展,不能绕过工厂直接实例化 - 这种运行时防护,是对“new 必须走指定路径”这一设计意图的技术兑现


















