抽象工厂模式是一种创建型设计模式,提供创建一系列相关或相互依赖对象的接口,而无需指定具体类;其核心是封装产品族的创建逻辑,确保类型一致性与解耦,不涉及异步行为。

new.target 不能用于实现异步抽象工厂,它和这个目标完全不匹配。
new.target 的真实作用
new.target 是一个元属性,只在函数或构造函数被 new 调用时才有值,用于检测调用上下文是否为构造调用。它返回当前正在执行的构造函数本身(或 class 的 constructor),常用于:
- 防止类被直接调用(非 new 方式)
- 在基类中判断子类是否正确继承并调用了 super()
- 辅助实现“只能被继承、不可实例化”的抽象类语义(配合 throw)
它不参与对象创建逻辑的调度,也不支持 await、Promise 或任何异步操作——它只是同步的、运行时的调用元信息。
抽象工厂与“异步”的本质冲突
抽象工厂模式的核心契约是:客户端通过工厂接口获取一组已创建完成、可立即使用的相关对象。它的“抽象”体现在产品族的类型契约上(如 IButton + ITextBox),而非创建时机。
所谓“异步抽象工厂”,实际要解决的通常是以下场景之一:
- 工厂需要加载远程配置、主题资源或插件包后才能确定具体产品类型
- 某些产品实例内部依赖异步初始化(如连接云存储、拉取 UI Schema)
- 想在 DI 容器中延迟解析/按需构造昂贵对象
这些需求应由异步初始化逻辑或依赖注入容器的生命周期管理承担,而不是把“工厂方法”强行变成 async 函数——否则就破坏了抽象工厂的接口一致性(有的工厂返回 T,有的返回 Promise<t></t>),导致客户端无法统一消费。
符合标准的替代方案
真正可落地、符合 ISO/IEC 14882(C++)或 ECMA-262(JS)及主流设计规范的做法是:
- 工厂保持同步,职责纯粹:只负责根据已有输入(环境变量、配置枚举、主题名)返回已构造或已注册的产品实例(或其工厂函数)
-
异步行为下沉到产品内部:例如
CloudUploadService构造后自动在init()中连接;客户端调用factory.createUploader()得到对象,再await uploader.upload() -
用异步准备阶段解耦配置获取:启动时预加载配置 → 注入 DI 容器 → 工厂从容器取服务。例如:
services.AddSingleton(sp => IsProd() ? new AliyunFactory(sp.GetRequiredService ()) : new LocalFactory());
这种结构清晰分离关注点,满足抽象工厂“封装产品族创建、客户端无感知具体类型”的定义,也兼容 TypeScript 类型系统和主流测试框架。










