事件采购:业务逻辑的放置位置

时间:2016-11-18 10:23:43

标签: events business-logic event-sourcing

我可以想到两个地方将域逻辑放在事件源系统中,或者有一个缺点。

  • 在Aggregate的事件处理程序中,在创建事件后在本地调用。 (这是我在大多数情况下看到的examples,尽管他们中的大多数都有非常简单的逻辑) 问题:存储在事件存储中并发布给订阅者的事件不包括此处理的数据,因此在投影中必须将相同的逻辑应用于事件。
  • 在创建活动之前。现在处理后的数据可以存储在事件中,并且投影不必知道任何有关业务逻辑的信息。 (我在实例中没有看到这种方法)
    问题:在这种情况下,虽然事件只包含可能导致信息丢失的已处理数据 更糟糕的是:由于已经计算了事件数据,我还放弃了通过重放事件来纠正错误的业务逻辑的可能性。

示例:根据某些数据计算指标  我必须两次计算度量(在域模型中一次,在投影中一次)
 或者我必须在发送活动之前计算它并将其包含在那里。

2 个答案:

答案 0 :(得分:6)

控制流程通常如下:

  • 命令被发送到命令处理程序,并且命令中的属性已经过预验证,就像身份指向现有实体并且所有必需信息都存在且格式正确
  • 命令处理程序从存储库中检索聚合(通过读取事件流,但这并不重要)并根据此命令需要执行的操作调用聚合方法
  • 聚合方法必须确保其参数和聚合状态相互允许执行操作。

  • 聚合方法然后创建一个事件并调用此WhenApply方法来处理事件

  • 事件处理程序会改变聚合状态,没有逻辑!

  • 然后将控制流返回给命令处理程序,并将其保留在商店中的所有新事件

进一步行动与预测有关。

在应用事件之前将不变保护(又称业务逻辑)放入聚合事件的原因是因为生成事件时没有回头路。这件事已经发生了。你不能拒绝申请活动。考虑从事件流中恢复聚合时重放事件(从存储库中读取),如果有一天您决定在那里组合if-throw,那么这可能会如何工作?

简而言之:

  • 在发送命令之前应用初始逻辑
  • 命令处理程序中有一些额外的逻辑
  • 聚合方法中的聚合保护(很可能也在命令处理程序中)
  • 事件处理程序中没有逻辑,只有状态变异

没有人说事件采购会帮助您解决计算中的问题。要建立一个额外的安全网,你可能想要保存命令,但是你必须发出补偿事件或截断流,这不是你想要做的。

答案 1 :(得分:0)

我想你的聚合根中有一些状态。这应包含有关您业务的逻辑。所以它应该有足够的数据来根据命令创建事件 此事件的消费者(查询模型)进行计算。因此,如果意图是计算平均值,则必须设法以给定的方式存储自己 我做了类似的事情。一旦它成为业务逻辑的一部分,那么它就在Aggregate中,一旦它在Query模型中,因为它不是业务逻辑的一部分,而是更多的度量计算。
不要害怕将数据存储在多个地方。一致性的责任应该委托给事件分发,而不是您的业务逻辑。