该技能用于在 TypeScript 项目中应用领域驱动设计(DDD),且仅适用于明确选择采用 DDD 的项目,不应将其模式应用到使用其他方法的项目。如需六边形架构(端口与适配器),应加载 hexagonal-architecture 技能;DDD 与六边形架构互补但相互独立。设计或更改物理放置时使用 structure-codebase 技能。若未请求物理重构,则保持仓库现有布局,同时隔离领域逻辑。
适用场景
DDD 对具有丰富业务规则的复杂领域有价值:领域包含复杂业务规则与不变量;存在多位具备领域知识的相关方;业务逻辑是核心差异化因素;术语具有特定且重要的含义。不适用场景:没有业务规则的简单 CRUD;以技术/基础设施为主的项目;没有可咨询的领域专家。建议从简单开始演进:先以统一语言(术语表)和值对象起步,只有当领域需要时才添加聚合、领域事件和限界上下文。
核心原则
代码必须使用领域语言。仓库声明的术语表是每个限界上下文的命名权威;命名已声明概念时应使用其规范拼写与大小写。术语表中不存在的概念属于待达成一致,既非自动批准也非禁止。领域模型会演进,首个模型从不是最终模型,重命名、拆分或合并聚合、涌现新概念都是预期且理想的。
代码归属判断
判断某段代码是否属于领域策略、应用策略、表现代码、基础设施/集成代码或框架入口点,使用该技能的框架逐层判断。纯度测试必要但不充分:一个用于显示的日期格式化纯函数不属于领域策略,而影响业务行为的规则(如事件是否已过)属于领域策略。领域策略代码通常有严格覆盖率要求且零基础设施导入。
构建块
- 值对象:不可变、无标识、按属性比较,如
Money;金额用整数最小单位存储和计算,不使用二进制浮点数主单位。跨信任边界的值对象使用 Zod 模式,领域内部可使用普通类型加工厂函数。 - 品牌类型:为每个实体设置专属品牌 ID,防止编译器接受跨实体 ID 混用;每个品牌类型只通过一个校验工厂进行一次品牌化。
- 实体:具有标识与生命周期,构造或状态转换后始终有效。
- 使非法状态不可表示:将实体生命周期建模为可辨识联合,每个变体只携带该状态有效的数据,并用
never保证穷尽处理。 - 聚合:单一根、所有修改通过根、按 ID 引用其他聚合、根强制所有不变量、保持聚合小巧。
- 规约(谓词函数):复杂业务规则以领域层谓词函数表达。
资源文档
resources/ 目录中按需加载:aggregate-design.md(聚合设计、拆分、大小问题、乐观锁)、domain-services.md(领域服务与用例区分、命名约定)、domain-events.md(跨聚合协调、Decider 模式、事件分发、流程管理器)、bounded-contexts.md(上下文边界、防腐层集成、上下文映射)、error-modeling.md(结果类型与异常取舍、错误传播)、testing-by-layer.md(分层测试、不变量属性测试)、references.md(DDD 来源依据、层归属与测试)。
限制
该技能不适用于未采用 DDD 的项目、简单 CRUD 或缺乏领域建模的项目。上述内容中未涉及具体收费、价格、平台或效果信息,暂未提供。