组合寄生继承是es5时代的手动类模拟方案,不适用于现代b端业务模型层,因其缺乏类型安全、与框架生态脱节、维护成本高;推荐采用dto+domain model分离、组合优于继承、状态机建模等现代工程化方式。
组合寄生继承本身不是现代 b 端系统业务模型层的主流或推荐方案。它属于早期 javascript 面向对象模拟手段(es5 时代),在大型 b 端系统中直接用于构建业务模型层,容易引发可维护性差、类型模糊、调试困难、与框架生态脱节等问题。
为什么不该用组合寄生继承建模
它本质是手动模拟类继承链,需反复操作 prototype、call、Object.create,代码冗长且易出错。在 TypeScript + React/Vue + 状态管理(如 Zustand、Pinia)已成为 B 端标配的今天,这种写法:
- 无法享受类型推导和编译期检查,字段缺失或误用只能到运行时报错
- 与现代依赖注入、响应式系统不兼容,难以接入 MobX 或 Vue reactivity
- 无法自然支持装饰器语法(如
@observable、@action)或 Hook 模式 - 模型实例无法被序列化/反序列化为标准 JSON,影响缓存、持久化与跨模块通信
真正适合大型 B 端的业务模型层构建方式
应以“契约先行、职责分离、可测试、可演进”为原则,采用更现代、更工程化的模式:
-
DTO + Domain Model 分离:API 层用接口定义的 DTO(TypeScript interface/type)做数据契约;领域逻辑封装在纯类(
class)或函数式工厂中,不继承,只组合。例如:CustomerModel.fromApi(data)做转换,而非靠继承链隐式赋值 -
组合优于继承:用策略对象、行为插件、配置驱动等方式复用能力。例如“审批流模型”不继承“基础单据模型”,而是通过
withApprovalFlow()组合器注入状态机与钩子 -
基于状态机建模:对生命周期复杂的业务实体(如合同、工单),用 XState 或自定义有限状态机描述状态迁移,模型层只暴露
send(event)和select(state),避免手工维护isDraft/isApproved等散落布尔字段 -
模型即服务(Model-as-Service):将模型逻辑下沉为独立可测试的 Service 类(如
OrderCalculationService),与 UI 层解耦。业务规则变更时,只需替换该服务实例,不影响视图结构
若历史代码中已存在组合寄生继承,如何安全演进
不建议重写,但可渐进升级:
- 为旧模型类编写 TypeScript 接口声明(
declare class LegacyOrderModel),逐步覆盖其行为 - 新建模块使用现代范式开发,通过适配器包装旧模型(
LegacyOrderAdapter.toDomain())对接新流程 - 用 ESLint 规则禁止新增
Object.create/call继承写法,推动团队统一建模规范 - 关键模型补充单元测试(Jest + Vitest),确保迁移前后行为一致,降低重构风险
本质上,B 端系统的复杂性来自业务规则本身,而不是继承关系的深浅。把精力放在清晰表达“客户能做什么、不能做什么、什么时候能做”,远比纠结用哪种 JS 继承技巧更有价值。










