DDD-只读聚合

时间:2019-06-06 21:49:09

标签: domain-driven-design aggregateroot

如果我们正在仅处理只读方案的子域中工作,这意味着我们的entitiesvalue objects不会被更改,那么创建它是否有意义由根及其子级组成的aggregates还是该上下文中的每个实体都应映射到单个aggregate

想象一下,我们有实体A和实体B

在进行修改的上下文中,我们创建一个由实体aggregate和实体A组成的B,其中Aaggregate root(让我们说B不能没有A生存,并且涉及到一些不变式)。

如果我们将同一实体移至未进行任何修改的不同上下文,那么保留此aggregate还是有意义的,还是应该为实体aggregate创建一个A和一个实体?实体B的另一个?

2 个答案:

答案 0 :(得分:2)

在2019年,对于在只读方案中您根本不用理会域模型的想法得到了相当大的支持。

只需将数据直接加载到支持该用例的任何只读数据结构中即可。

另请参阅:

答案 1 :(得分:1)

第一件事是,如果B没有A就无法生存,并且涉及到一些不变式,对我来说A是一个聚合根,而B是属于它的实体。

聚合根代表一个现实世界的概念,并且为了修改的方便而存在。在我们的许多应用中,一旦创建,我们就不会修改聚合根的状态-也就是说,我们实际上具有不可变的聚合根。这些将具有通过合同检查/不变检查等进行设计的逻辑,但是它们实际上是贫乏的,因为由于其不可变性而没有“更新”方法。自从“蓝皮书”由埃里克·埃文斯(Eric Evans)撰写以来,很多事情都发生了变化,例如NoSql数据库的概念已变得非常流行,功能性编程概念已变得非常有影响力,并逐渐上升到推荐使用的更高级的DDD样式体系结构,例如CQRS。因此,例如,除了对数据库进行更新,我可以附加(即插入)。这导致不再需要“更新”聚合。这导致贫血的贫血类型,但这是我们在这种情况下想要的。贫乏类型之前的问题是,给定类型的“更新逻辑”被放置在代码库中的其他位置,而不是放置在类型本身中。但是,如果您首先不需要“更新逻辑”,那么您就不会遇到问题!

例如,如果某个订单包含许多OrderItem,我们将创建一个Order聚合根和一个OrderItem实体。提取您的域以正确识别什么是聚合,实体和值类型是一个非常重要的概念。

然后,域服务,存储库等的创建就自然地进行了。例如,集合的根和存储库为1到1,即,在上面的示例中,我们将有一个Order存储库,而没有OrderItem存储库。这样,您的主要领域概念便以一种可预测且易于理解的方式遍及整个代码。

最后,在您的特定问题中,我不会将它们视为相同的实体。在一种情况下,您似乎需要修改逻辑-在您不需要的另一种情况下-它们对我来说是独立的领域概念。

  • 在进行修改的上下文中:A =根,B =实体。
  • 在未经修改的情况下:A = agg根(不可变),B =实体(不可变)