在ES中组织我的事件流的最佳方式是什么。对于事件流,我指的是聚合的所有事件。
鉴于我有一个project
包含一些数据和一个tasks
列表。
现在,我Guid
的{{1}}为AggregateID
。
到目前为止,我可以
- >使用该ID重新创建给定项目的状态
- >我可以使用自定义投影
streamID
列表
问题是如何处理projects
?
是否应该在todos
project
下方处理,还是应该拥有stream id
?
如果todo stream id
将其分开todo
,将如何将其与拥有stream
相关联。 project
如何了解给定project
的所有todo streams
。
这意味着对project
的所有更改都应该在项目中被识别为todo list
和Commands
(更多事件)。
如果我还想允许Events
与项目无关。是否需要拥有自己的类型并free todo's
来处理stream
。所有freeTodo
的所有todos
列表是否与所有project
和todo
相关的流有关?
所以我想主要的问题是我如何处理嵌套聚合以及如何定义事件存储流及其链接?
任何提示,技巧,最佳实践或资源都将受到高度赞赏。
//编辑更新
首先,谢谢@VoiceOfUnreason花时间详细回答这个问题。我添加了标签DDD,因为我有一种奇怪的感觉,它与有界的背景问题相关,这个问题大多数时候都没有黑色或白色的决定。显然,域名有更多的深度和细节,我简化了示例。在下面,我分享了一些让我质疑的细节。
在我的第一个想法中,我为freeTodo
定义了一个聚合,并为todo
定义了一个属性。我将此project id
属性定义为project
,以涵盖项目相关和免费待办事项之间的差异。但是,以下用例/业务规则让我重新思考。
系统还应包含免费option type (Nullable)
,允许用户安排与项目无关的个人todo's
(人力资源培训等)。所有tasks
都应显示在todo's
或完整projects
列表中(项目相关且免费)。
只有完成所有todo
后才能完成/关闭project
。
这会将来自todo's
的某些信息与来自aggregate project
的信息混合在一起。所以这里没有明确的界限。我的想法是:a)我可以利用aggregate todo
中的todo read model
进行验证。 b)在项目聚合范围内为project aggregate
定义某种列出的结构(如果是这样的话)。这将处理项目上下文中的待办事项并定义明确的界限
c)提供某种服务,为项目验证提供todo's
个信息,以某种方式指向a点。)。
所有感觉真的耦合= - /
如果您或某人有时间在这里分享更多细节和意见,那将会很棒。太感谢了。
答案 0 :(得分:6)
提醒:ddd中的战术模式主要是OO最佳实践的枚举。如果在OO中这是一个坏主意,那在DDD中可能是个坏主意。
主要问题是如何处理嵌套聚合
您重新设计了模型。
嵌套聚合表明你完全丢失了情节;聚合边界永远不应重叠。重叠边界类似于封装违规。
如果todo有单独的流,那么如何将它链接到拥有项目。
最可能的答案是Todo会有一个projectId属性,其值通常指向系统中其他位置的项目。
项目如何了解给定项目的所有待办事项流。
不是。您可以构建组成项目历史和todos历史的读取模型,以生成单个只读结构,但项目聚合 - 负责确保边界内状态的完整性 - 不会t看看todo对象。
意味着对todo列表的所有更改都应该在项目中被识别为命令和事件(更多事件)。
不,如果它们是单独的聚合,则事件是完全独立的。
在某些情况下,您可以将todo生成的事件中的值用作调度到项目的命令中的参数,反之亦然,但是您需要将它们视为具有可能的对话的单独事物,或者可能不会达成协议。
可能性:可能是自由站立的待办事项与项目相关的待办事项实际上是不同的东西。请咨询您的域名专家 - 他们可能会使用无处不在的语言单独的术语,或者讨论您可能会发现他们 在UL中有不同术语的详细信息。
或者,todo可以是单独的聚合,并且业务适应接受这样的事实:有时项目的状态和todo的状态不一致。您可以检测差异并在必要时缓解问题,而不是试图阻止模型进入聚合不同意的状态。