所以我是DDD的新手,我正在尝试正确设计一个应用程序。但是我在识别聚合根时遇到了一些困难。
我的需要或多或少是一棵树
*Customers
*Each customer can have 0 or more licenses
*Each license can have 0 or more courses
*Each course can have 0 or more lessons
*Each lesson can have 0 or more slides and videos
最后,我的测验/测试几乎可以与任何内容相关联,甚至在课程视频中的某个时间。
无论我如何思考,我只会得到客户将是包含[客户,许可,课程,课程,幻灯片,视频]的聚合的聚合根
但这是一个相当大的集合,我已经明白应该避免大的聚合。
测验将是一个包含问题,答案等的汇总。 作为第二个问题,我可能会问这个链接应该是什么样子?因为我想说我想在4分钟后在视频中弹出一个测验。 那么我的测验需要链接到该视频并存储时间。 但该视频深入到另一个聚合(在客户,许可,课程,课程下)并且不应该直接从这个测验聚合中直接链接。
那么我该怎么解决呢。 我订购了我的大DDD书,但它不会在这里待一段时间,如果我能理解这一点,那么它会很棒!
我不应该重要,但我使用.net c#mvc,使用ef5和存储库模式。
答案 0 :(得分:2)
为简化起见,您应该使用CQRS,即使用不同的模型进行“书写”和查询。这意味着我们有2个案例 1.创建和更新业务对象(实体) 2.从业务对象生成简化模型以允许简单查询
使用这种方法意味着您可以专注于对客户,许可证,课程,课程进行建模,以便对建模真实行为和它们之间的关系进行建模。
这里很容易陷入以数据为中心的方法,即客户被视为许可证的容器,而许可证又是课程的容器等。这些实体是聚合根,但很明显(即使没有太多信息)不是容器。
将思考课程组织成根据许可证组织的课程可能更合适。这意味着课程实体与某些课程实体相关联,因此课程实际上没有课程。它有一个名称,一个教学大纲等。课程,教授,学生“附加”课程,但不是课程的一部分。
客户实体为客户建模。当客户购买一些许可证时,他会获得访问与该许可证相关的课程的权利。客户再次没有许可证。因此,您需要对客户与许可证之间的关联进行建模。在这样做时,想想LIcense的细节取决于客户的细节(他们没有机会,因为他们是完全不同的东西,所以基本(CustomerId,LicenseId)就足够了)。当然,这些都是简单的建议,因为我不确切知道域名。
重点是,您必须深入了解客户,许可等对域的意义,并抵制以“明显”的方式查看事物的冲动。 DDD建模并不难,但它非常棘手,因为你真的不能表面上看它。
答案 1 :(得分:1)
您应该在业务不变量之后定义聚合。
在弗农的essay on aggregate design抓一个战利品 要关联不同的聚合,您可以使用shared identifiers,这也消除了对lazy loading的需求。
但是,您还应该考虑是否必须设计不同的有界上下文。与您的领域专家交谈,解释每个有限的背景与特定的观点有关。