优雅封装基于属性检查的工厂函数需解耦判断与构造逻辑,用Symbol替代字符串标识类型,策略表注册test/create函数,泛型约束确保类型安全,并可选缓存对象结构提升性能。

优雅封装基于属性检查的工厂函数,核心在于把“判断逻辑”和“构造逻辑”解耦,同时保持调用简洁、扩展性强、类型友好。不靠一堆 if-else 堆砌,也不让工厂变成上帝对象。
用 Symbol 作类型标识,避免字符串硬编码
用字符串判断类型容易拼错、难重构。改用唯一 Symbol 作为“类型标记”,既语义清晰又支持 TS 类型推导:
- 每个类定义一个静态 Symbol 属性,如 Symbol.for('ShapeType')
- 工厂函数只检查该 Symbol 值,不依赖类名或任意字段名
- TS 中可配合 declare 合并类型,让类型系统识别该 Symbol 的含义
把判断规则抽成可注册的策略表
工厂不该修改自身代码来支持新类型。把“属性存在性 + 类型/值约束”封装为策略项,统一注册:
- 每个策略是一个对象:{ test: (obj) => boolean, create: (obj) => Instance }
- test 函数专注检查(例如:'radius' in obj && typeof obj.radius === 'number')
- create 函数专注实例化,与判断完全隔离
- 支持按需动态 register() 新策略,无需改工厂主逻辑
返回带明确类型的泛型工厂,而非 any 或 unknown
直接 return obj 可能丢失类型信息。用泛型约束输入,并用类型守卫或 satisfies 确保输出精确:
- 函数签名类似 <T extends Record<string, unknown>>(obj: T): ShapeInstance
- 对常见结构预设联合类型(如 CircleInput | RectInput),再用 satisfies 校验输入是否匹配
- TS 5.0+ 可结合 const type 参数实现更精准的返回类型推导
加一层缓存策略,避免重复判断同一对象结构
若工厂高频调用且输入对象结构稳定,可对“对象形状”做轻量缓存:
- 用 Object.keys(obj).sort().join('|') 生成简易 shape key
- 命中缓存时跳过所有 test,直接走对应 create
- 注意仅适用于不可变或结构极少变动的场景,避免缓存污染

















