在没有事件存储的系统中,我应该避免使用聚合(DDD)吗?

6
我正在考虑在没有事件存储的系统中采用领域驱动设计中(根)聚合的概念。然而,我发现更多关于两者的信息后,感觉它们相互依存,缺一不可。
我还没有读完蓝皮书,但到目前为止,我对根聚合的理解是它是聚合的“树”,需要在该根聚合内保持一致。一个聚合只能通过它所属的根聚合来修改。最后,一个根基本上可以通过“在这个领域中独立存在并且可以单独存在”的定义来定义。
想象一下一个全新的项目,在这个项目中,还没有必要使用事件源码,但未来可能会受益于它。缺少事件存储将消除跟踪特定时间点上形成根聚合的所有领域事件的可能性。命令将不得不改变根聚合。此外,由于无法重放事件,读取端将受限于“根聚合{id}已更新”的反应。
根据以上情况,有没有合理的方法让(根)聚合的概念在没有事件存储的情况下存在,或者应当坚持“传统”的实体建模直到投资于事件源码有意义?
1个回答

12

我觉得你搞混了一些概念。并不存在所谓的根聚合或聚合树。

DDD中聚合战术模式存在的主要目的是为了定义一致性边界,从技术上来说就是事务边界。当你处理单个命令时,聚合内部的所有内容都可以更改,但不能超过聚合边界。

一个聚合可以由多个实体类型组成,但只有一个实体类型作为聚合根。聚合根ID是整个聚合的标识。聚合内的其他实体将有它们自己的ID(否则这些不是实体而是值对象),但这些实体不能从聚合外部直接修改或引用,并且在一个聚合内的所有实体操作都通过聚合根进行。

聚合最典型的例子是“订单”,其中“订单”本身(或者如果您喜欢,则是“OrderHead”)是根,而“OrderLine”是实体。您可以为一个订单拥有多个订单行,但对任何订单行的所有操作都必须经过根执行。

聚合模式与事件溯源之间没有直接明确的联系。事件溯源是具体实现的细节。Eric Evans的书甚至没有提到事件溯源,但其中有很多聚合的示例。

事件溯源是一种持久化数据的方式。实际上,事件溯源与DDD没有任何关系,尽管Greg Young最初建议使用事件溯源来通过存储领域事件来持久化聚合。

当您拥有纯领域模型时,从领域模型的角度来看,您使用哪种持久化机制并不重要。许多事件溯源系统根本没有聚合的概念。例如,纽约时报构建了一个基于事件溯源的内容管理系统,而没有考虑任何DDD战术模式。另一方面,使用战术DDD模式的大多数系统不使用事件溯源,而只使用基于状态的持久化。


1
我只想补充一下@Alexey的精彩回答,并提到在使用事件溯源时,您的聚合设计与传统方法略有不同,因为您将会将事件作为输出发布到您的命令并存储它们以进行重放。一个更传统的方法是以某种其他方式存储和重新生成聚合的状态。我目前正在开发一个现有的网络数据包捕获系统,其中解码和分析交易/清算平台消息,并遵循事件溯源概念,看不到DDD :) - Eben Roux
谢谢您,回答清晰明了,很有帮助!您说得对,我混淆了聚合作为一种策略而不是一种实体的概念。我以为聚合是实体的替代品。我还以为当我以规范化的方式持久化数据时,我违反了聚合原则。结合@Eben的评论,我意识到我可能已经在使用聚合策略了。我确实将规范化数据重新转换为“根实体”,并通过该“根聚合”程序性地修改相关实体。这些指针应该会对我有所帮助,再次感谢! :) - Mattias Nixell
感谢对事件溯源的阐述,它并非必需品。谢谢@Alexey。 - D_Edet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接