全局事件是否可以接受?

时间:2015-05-16 11:19:33

标签: domain-driven-design event-sourcing aggregateroot

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

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

这可能会导致以下事件:

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

重播上述事件流会导致帖子中包含标题,内容和两个标签(“Foo”和“Baz”)。

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

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

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

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

TagCreated("NewTag")

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

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

2 个答案:

答案 0 :(得分:0)

恕我直言,你的生活变得更加复杂。域事件通常可以跨越有界上下文,它们应该通过引用其id与聚合根(AR)相关联。

在您的示例中,我将标记视为值对象,因此需要帖子ID。但是如果你想让Tag本身可用,那么它就是一个AR,因此,该事件将具有TagId属性。

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

答案 1 :(得分:0)

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