mcpField
D
ddd-entity

ddd-entity

github.com/yonatankarp开发145 次安装24 周前更新
代码仓库

关于 ddd-entity

ddd-entity 是介绍领域驱动设计中实体建模的技能,面向设计领域模型的开发者。它强调稳定身份、生命周期和维护不变量的行为,并与值对象等概念作出区分。

主要功能

  1. 01说明实体身份与相等性
  2. 02介绍实体生命周期
  3. 03强调通过行为维护不变量
  4. 04提供实体和值对象的判断依据
  5. 05指出贫血实体等反模式

适用场景

  1. 01建模需要持续追踪的客户或订单
  2. 02区分属性相同但身份不同的对象
  3. 03判断领域概念应建模为实体还是值对象

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/yonatankarp/software-design-skills --skill ddd-entity

安装后在 Claude Code 中输入/ddd-entity确认已加载。

详细介绍

单行概述

实体是一种领域对象,它由自身身份而非所包含的内容来识别——即使属性发生变化、时间流逝,其身份仍保持不变。

何时使用此技能

  • 建模需要随时间跟踪的对象:Customer、Order、Account、Shipment、Subscription。
  • 两个属性完全相同的实例仍然是不同的事物(“两个名叫 John Smith 的客户并不是同一个客户”)。
  • 某个概念具有生命周期——创建、修改、归档、删除——且同一个概念实例会在这些状态间持续存在。

何时不使用此技能

  • 某个概念完全由其属性描述,且没有身份 → 使用 ddd-value-object。
  • “身份”只是没有领域含义的数据库自增 ID → 这表明该概念或许其实是值对象,只是持久化层为了存储而为其标识了身份。
  • 某个概念只存在于单个聚合内部,从未在外部被引用 → 它仍可能是实体,但请重新考虑是否需要将其单独建模。

核心内容

身份是实体的区分特征。实体的身份是分配的(通常是 UUID、客户编号之类的业务标识符,或自然键),且稳定不变——属性发生变化时,身份不会改变。相等性由身份决定:当且仅当两个实体的标识符相同时,它们才相等,与其他所有字段无关。

实体具有生命周期。它们会被创建(通常通过工厂)、通过能够维护不变量的方法进行修改,也可能被归档或删除。在整个生命周期中,身份保持不变。

实体应体现行为,而不只是数据。Customer 实体可能包含 changeAddress、closeAccount、deactivate 等方法。每个方法都负责维护实体的不变量——客户的状态绝不会不一致。

判断启发

  • 如果需要跟踪某个对象的历史,或日后引用“同一个对象”,它就是实体。
  • 如果可以轻松地用另一个属性相同的实例替换它,它就是值对象。
  • 如果某个候选概念是实体,但除了 getter/setter 之外没有任何行为,请提出质疑:这个实体要么是贫血实体(应添加行为),要么分类有误(它可能其实是值对象)。
  • 身份是分配的,而非从属性推导得出。如果你发现自己在通过字段推导身份,那你很可能是在建模值对象。

反模式

  • 将每个领域对象都建模为实体,包括那些没有固有身份的对象(“实体泛滥”)。
  • 没有行为的实体——仅包含字段和 getter 的“贫血实体”。参见 ddd-anti-patterns。
  • 用属性相等性取代身份相等性(语言适配器的常见陷阱——Kotlin 的 data class 默认如此)。
  • 将数据库行的自增 ID 当作领域身份。

另请参阅

  • ddd-value-object — 相反的情况:没有身份的概念。
  • ddd-aggregate — 实体通常充当聚合根。
  • ddd-factory — 用于创建构造过程较复杂的实体。
  • ddd-repository — 用于按身份加载和保存实体。
  • ddd-anti-patterns — 贫血实体、标识符中的原始类型迷恋。

参考资料

  • Evans,《领域驱动设计》(2003),第 5 章(以软件表达的模型)。

评论

支持 Markdown