DDD - 对聚合之外的实体的引用

时间:2017-12-13 06:34:50

标签: reference entity domain-driven-design aggregateroot

这是我第一次尝试使用DDD,我想就建模问题提供建议。

这是我的域名:多所学校的管理。

  • 学校有多个学生老师,......
  • 对于一所学校,(每年)都有一个新的 schoolYear (例如,其中有一个值对象持有2017-2018
  • 课程学生成绩与学校相关(例如,学生A可以在2017-2018学年的C1班和2018年的classe C2 -2019)

我的第一个疑问是 schoolYear 的建模。

我已经将 school 实体作为根聚合。我的第一个方法是让 school 聚合处理 schoolYear 的添加(这样我可以避免重复,或者我可以创建下一个 schoolYear ,...)

=> schoolYear 学校汇总

的一部分

但后来我不得不模拟学生成绩 ......这取决于 schoolYear

所以在我的 classes 聚合中,我必须持有对 schoolYear 的引用...这违反了规则

  

“无法从外部聚合中保留对内部实体的引用。”

在我的域中,许多实体依赖于特定的 schoolYear 。也许它应该是一个聚合......

另一方面,给定 schoolYear 用于搜索类。

我可以就此建模问题获得一些建议吗?

另一个依赖性问题是关于 schoolYear 的身份。

  • 选项A:按原样生成UUID并将 schoolId + 作为属性
  • 选项B:我是 schoolId ,因此我们无法为同一个学校创建相同的 schoolYear 两次和同年

对此有何建议?

非常感谢帮助我进入DDD世界!

2 个答案:

答案 0 :(得分:5)

要回答你的问题,我必须做出一些假设。所以也许我的回答并不能完全反映你的实际意图,但我试图尽可能地遵循你所描述的内容。因此,请带上我的答案。

首先,引起我注意的是你正在考虑一个对象模型。域驱动设计不是关于对象,而是关于过程。因此,虽然你专注于名词,但我建议你更多地关注动词:你的领域中可能发生的事情是什么?

在考虑这个问题时,我更清楚的是, :是的,您需要找到学校最初,但一旦成立,随着时间的推移,并没有很多行动。也许它会被重命名,但就是这样。

schoolYear 也是如此。我的假设是(我不知道这对你的具体情况是否正确),例如,2017/2018年只有一个学年对所有学校都有效。也许这在你的场景中有所不同,因为不同的学校可以有不同的学年,但我认为它们总体上是相同的。

此外,还有教师学生,这些都是非常简单的事情。

这给我们留下了。最初,课程为特定学校和特定学年获得设置。然后你分配教师(我假设每个班级只有一名教师,我也假设可以将一名教师分配到多个班级)。然后学生加入课程,或离开。最后,一年一次,你移动班级到下一学年。

这意味着应该是一个聚合,它知道它属于哪个学校和学年,哪个有老师,并且包含已注册学生的列表。您可以在此课程中使用命令,例如:

  • 设置(学校,学年)
  • assign(老师)
  • 加入(学生)
  • 离开(学生)
  • move(schoolYear)

然后,学校只是另一个聚合,它具有如下命令:

  • 结果
  • 重命名

同样, schoolYear 可以是简单的聚合,其命令如下:

  • 开始

对于教师学生 - 嗯,他们也是聚合。我不会在这里明确列出他们的命令,但我认为你可以自己提出它们。

最后,我相信,正如所说的,你应该更专注于动词和可能发生的事情,而不是名词。一旦你这样做,你需要考虑哪些动词可以同时发生,因为它们不会相互干扰,哪些动词不能同时发生。这导致您如何定义聚合,因为聚合是事务边界,限制哪些操作可以同时发生,哪些操作需要按顺序运行。

documentation of wolkenkit,我和我的同事正在研究的JavaScript和Node.js的CQRS和事件采购框架中,有一个很好的描述如何与您的团队进行建模。也许它对你有帮助。

希望这会有所帮助: - )

答案 1 :(得分:-1)

关于SchoolYear身份的问题。如果您确定schoolId一旦创建后就不会更改,那么我建议使用schoolId-year代替UUID,因为它比UUID更具描述性。但如果schoolId-year是聚合,请确保组合,即SchoolYear全局唯一。