如果我们正在仅处理只读方案的子域中工作,这意味着我们的entities
和value objects
不会被更改,那么创建它是否有意义由根及其子级组成的aggregates
还是该上下文中的每个实体都应映射到单个aggregate
?
想象一下,我们有实体A
和实体B
。
在进行修改的上下文中,我们创建一个由实体aggregate
和实体A
组成的B
,其中A
是aggregate root
(让我们说B
不能没有A
生存,并且涉及到一些不变式)。
如果我们将同一实体移至未进行任何修改的不同上下文,那么保留此aggregate
还是有意义的,还是应该为实体aggregate
创建一个A
和一个实体?实体B
的另一个?
答案 0 :(得分:2)
答案 1 :(得分:1)
第一件事是,如果B没有A就无法生存,并且涉及到一些不变式,对我来说A是一个聚合根,而B是属于它的实体。
聚合根代表一个现实世界的概念,并且为了修改的方便而存在。在我们的许多应用中,一旦创建,我们就不会修改聚合根的状态-也就是说,我们实际上具有不可变的聚合根。这些将具有通过合同检查/不变检查等进行设计的逻辑,但是它们实际上是贫乏的,因为由于其不可变性而没有“更新”方法。自从“蓝皮书”由埃里克·埃文斯(Eric Evans)撰写以来,很多事情都发生了变化,例如NoSql数据库的概念已变得非常流行,功能性编程概念已变得非常有影响力,并逐渐上升到推荐使用的更高级的DDD样式体系结构,例如CQRS。因此,例如,除了对数据库进行更新,我可以附加(即插入)。这导致不再需要“更新”聚合。这导致贫血的贫血类型,但这是我们在这种情况下想要的。贫乏类型之前的问题是,给定类型的“更新逻辑”被放置在代码库中的其他位置,而不是放置在类型本身中。但是,如果您首先不需要“更新逻辑”,那么您就不会遇到问题!
例如,如果某个订单包含许多OrderItem,我们将创建一个Order聚合根和一个OrderItem实体。提取您的域以正确识别什么是聚合,实体和值类型是一个非常重要的概念。
然后,域服务,存储库等的创建就自然地进行了。例如,集合的根和存储库为1到1,即,在上面的示例中,我们将有一个Order存储库,而没有OrderItem存储库。这样,您的主要领域概念便以一种可预测且易于理解的方式遍及整个代码。
最后,在您的特定问题中,我不会将它们视为相同的实体。在一种情况下,您似乎需要修改逻辑-在您不需要的另一种情况下-它们对我来说是独立的领域概念。