【问题标题】:CQRS - Generate multiple commands from one formCQRS - 从一种形式生成多个命令
【发布时间】:2017-09-08 21:04:12
【问题描述】:

我遇到了一个问题,不知道该怎么办。

我的域名:
我有一个 Booking 实体,是 booking 业务上下文 的根。
Booking 内部存在 Event(s) 集合,即用户创建的真实事件列表。 Booking看起来有点没用,但是整个系统把Booking链接到其他实体,所以它确实是业务的根源。
Event 可以有文本注释,因此我创建了一个 Notes 实体。我使用实体是因为笔记可能会随时间变化,它们链接到 事件 并且不能共享。 Notes 实际上绑定在 booking 业务上下文 中并聚合到 Booking 根实体。

表单(创建事件):
我有一个用于提交“事件”的表单。实际上,表单的数据会生成一个命令,其中包含创建新 Event 所需的所有信息,如果用户愿意,还可以生成它的 Notes

命令(创建事件):
从表单创建命令并将其发送到服务器。该命令有事件的数据。
服务器上的处理程序对主实体 Booking 进行操作,创建一个新的 EventEvent 可能有也可能没有Notes,这取决于用户在表单中输入的内容。

booking 业务上下文 处理的其他命令是:

  • 删除事件
  • 取消一个事件(为无法发生的事件创建一个特殊事件),将来它还可以用于添加注释(事件被取消的原因)
  • 为取消的事件创建备份事件

另一个实际上在这个上下文中的命令是

  • 更新事件备注

我的问题来了:
无需处理 Event 即可进行更改,是否可以将 Notes 提升为根实体并且它们是业务上下文?所以,我最终会为 BookingsNotes 提供一个上下文。
实际上,要更改 Notes 并保留在 DDD 上下文中,因此不要暴露太多,我必须进行一些“跳转”来执行更改。它有效,是的,但它很丑。如果我拆分这些东西,也许它会更优雅,并且限制在正确的上下文中。

另一方面,如果答案是 yes,我该如何处理第一个命令,它会生成带有 NotesEvent ?同样的问题也适用于取消。
我无法从表单中触发两个命令,一个依赖于另一个,因此顺序很重要。
也很难创建一个处理程序(最后是一个事件监听器),在创建/取消成功完成后,它会触发第二个命令来更改 Notes。如何识别正确的事件?必须使用表单发送的数据创建侦听器,以匹配要处理的事件。

【问题讨论】:

  • 我不明白你所说的“上下文”是什么意思,是不是来自 DDD 的“有界上下文”?
  • 是的,我只是使用了错误的名称。有界上下文,而不是业务上下文。

标签: domain-driven-design cqrs


【解决方案1】:

在 Booking 中存在 Event(s) 的集合,即列表 由用户创建的真实事件。预订看起来有点没用,但是 整个系统将 Booking 链接到其他实体,所以它真的 企业的根。

据我了解,Booking aggregate root 没有必须保护的不变量。即使Event 属于Booking,如果没有规定某些事件组合不应该存在的规则,那么Event 也应该是Aggregate root

所以,CreateEventCommand 应该包含BookingIdEventId 和一个可选的notes

Notes 实际上绑定在预订业务上下文中,并且 聚合到 Booking 根实体

我不太同意这一点。注释属于EventEvent 属于Booking,所以Note 链接到Booking 是正常的,但是没有不变量将Note 链接到Booking , 只有ID 的关联是DDD 在任何情况下都允许的。

Notes 可以提升为根实体并且它们是业务上下文吗?

是的,如果没有必须由Event AR 保护的不变量。然后,CreateNewNoteCommand 应该包含BookingIdEventId

创建处理程序(最后是事件侦听器)也很困难 也就是说,在创建/取消成功完成后,它会触发一个 第二个命令更改注释。如何识别权利 事件?必须使用表单发送的数据创建侦听器,以 匹配要处理的事件。

确实,设计给了你一个反馈,你做错了。如果您正确设计了Aggregates,则不应发生这种情况。如果事情看起来变得非常复杂,那就回去重新考虑你的设计。 DDD 非常注重重构。

【讨论】:

  • Mhh...确实,我在想Event是否也必须是Aggregate root。到目前为止,我没有这样做的原因是 Booking 是在有限的时间范围内(一个学期)创建的。 Event 不能在学期范围之外创建。该控制应该并且只能在 Booking 内完成。
  • @user3604315 没关系。如果无法创建 Booking ,则您没有 ID ,那么您将无法创建 CreateEventCommand 。这不是真正的Aggregate 不变量。
  • 关于Notes,它们实际上绑定到Event,我写错了。而且,确实,Event 没有要保护的不变量。所以,他们可以被提升为Aggregate root。但是,现在它们是实体,因为 db 需要一个 id(是的,它是一个序列,我无法控制 - 几乎无法控制它)。我在想是否可以将它们视为可变值对象的特例。事实上,它们只与Event 一起存在。我认为这会简化一切。
  • 最后,如果我将Event 提升为Aggregate root,我在哪里可以控制日期在学期内?在命令处理程序中,我是否应该加载 Booking 并检查日期是否“兼容”?
  • 我没有发现问题。 aggregate root 可以有sub-entities,你不需要mutable VO。请注意,在 DDD 中,aggregate root 创建所有嵌套实体。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多