领域驱动的设计——聚合范围的事件是否可接受



在使用事件源的应用程序中,是否可以接受具有聚合范围的事件?

考虑一个虚构的博客应用程序示例,该示例提供了创建帖子以及添加和删除简单标记的能力(post将是聚合根)。

这可能导致以下事件:

PostCreated: postId, "title", "content"
TagAdded: postId, "Foo"
TagAdded: postId, "Bar"
TagAdded: postId, "Baz"
TagRemoved: postId, "Bar"

重播上述事件流将产生一个带有标题、内容和两个标签("Foo"&"巴兹")。

现在想象一下用户界面只允许你在创建帖子时选择现有的标签,而不接受自由文本;只有特权用户才能更新标签的主列表。

现在,当特权用户创建新标记时,需要创建相应的事件,以便a)信息实际存储在事件存储中,b)在某个时刻更新读取模型,以便创建博客文章的用户可以在UI中选择新标记。

拥有一个看起来像TagCreated: postId, "NewTag"的事件对我来说似乎是不对的,因为信息不能直接应用于单个帖子。

考虑到在这种情况下,信息不保证它自己的聚合根,并且只会在这个有限的上下文中使用,我希望事件沿着以下行:

TagCreated("NewTag")

这些事件将存储在事件存储中,使用与前一组特定帖子事件相同的聚合id,但没有特定聚合实例的id。

到目前为止,这听起来像是一个合乎逻辑的方式来处理问题,但我想知道我是否错过了任何明显的接近它的方式。

恕我直言,你把生活复杂化了。域事件通常是跨界上下文可用的,它们应该通过引用聚合根(AR)的id与聚合根(AR)相关联。

在你的例子中,我认为标签是一个值对象,所以它需要一个post id。但如果你想让标签本身可用,那么它将是一个AR,因此,该事件将具有TagId属性。

顺便说一句,域事件是一个DTO,意味着在任何地方都可用,它们不是需要封装在聚合中的域细节。

我想你错过了"标签目录"之类的概念。它可以有一个单一的聚合(或者您可能有时会为不同的用户组有几个目录或类似的东西),目录作为根,包含所有标记作为值对象。

最新更新