领域驱动设计 - 大型儿童系列

时间:2014-05-07 20:04:14

标签: c# domain-driven-design repository aggregateroot

问题

如何在DDD中实现大型集合“感觉”它们应该是聚合根的一部分,但如果它们是不切实际的话,那将是不切实际的吗?以下是基于我的域名的一些示例。

Employee聚合根

  • Announcements收藏
  • 直接Messages收藏

Product聚合根

  • Stock项目集合

等。等。

我在想什么

我想保留从聚合根导航到这些大型集合的能力,但由于我用存储库包装我的O / RM延迟加载实际上不是一个选项...除非我通过注入实现延迟加载要么是必要的存储库。但我从我所读到的关于DDD的内容中知道,域实体不应该知道任何这样的存储库..

另一种选择是采用以下方法:我的域中任何可能很大的实体集合是聚合根,并且应该拥有自己的存储库,其中包含所需的接口以获取项目集合另一个聚合根。例如

public interface IStockRepository
{
    IEnumerable<StockItem> FetchByProduct(Product product);
    // ...
}

2 个答案:

答案 0 :(得分:2)

这个&#34;我希望能够从聚合根&#34;导航到这些大型集合。 ......是一种气味。你似乎很痴迷,如果你不介意我说,你的聚合结构,而不是它的行为,它正在解决的问题,任何发挥作用的不变量。坦率地说,你的感觉是错位的。它是我们结构化,数据库导向思维方式的残余。

总的来说,我要说,首先不应该有这些大型收藏品。对于一次加载,它们将需要更好地在其他地方使用的资源(内存,CPU,带宽)。从更具功能性的角度来看,人们往往不会立刻处理大量的事情,甚至计算机也可以在你将事情分解为工作单元时做更多的工作。因此,尽量远离大型藏品,并始终质疑&#34;为什么&#34;你首先需要它们。

公告可以是它自己的汇总,通过其id引用员工,因此我们知道公告是关于谁(或为?)。如果公告针对的是员工组,您可能需要查看定义该组的内容,并明确对其进行建模。直接消息也可以是它自己的聚合,因为它可能是从一个人到另一个人的消息。可以说员工的角色是成为邮件收件人和/或发件人。再次,通过id引用员工聚合可能就足够了。可以单独处理库存项目,并通过其productid引用它在库存中表示的产品。员工的行为,公告,直接信息,产品,股票项目是什么?如何以及何时改变其合作者的状态会影响他们,真的,为什么呢?它是一个根本原因的手段。找到它。

所有这一切,有时你可以稍微改变规则,但它们应该很少。

答案 1 :(得分:1)

看看Vaughn Vernon的论坛DDD示例。他从聚合根中模拟了大型集合。创建是通过聚合上的工厂方法完成的,以控制某些事情,就像在论坛关闭时无法创建一个dicussion。行动通过AR论坛完成(如startDiscussion和moderatePost)。

该方法返回一个实体(Post),该实体需要由应用程序服务保存在单独的存储库(PostRepository)中。现在,您可以拥有大型集合,而无需每次都加载。

https://github.com/VaughnVernon/IDDD_Samples/tree/master/iddd_collaboration/src/main/java/com/saasovation/collaboration/domain/model/forum