在EventSourcing中将业务逻辑应用于何处

问题描述

在事件外包中,我对于到底必须在何处应用业务逻辑感到困惑。我已经在Google中进行了搜索,但是所有示例都是非常基本的,即从事件对象更新Handler中对象的状态,但是在我的另一种情况下,对于到底应该在何处应用业务逻辑,有些困惑不明白。 >

例如:例如,让一个场景更新 IntervieweeVO 的状态,该状态位于 Interview聚合类中,如下所示:

class Interview extends AggregateRoot {

  private IntervieweeVO IntervieweeVO;

}

class IntervieweeVO {
  int performance;
  String status;
}

class IntervieweeSelectedEvent extends BaseEvent {
  private IntervieweeVO IntervieweeVO;
}

我有一个业务逻辑,即,如果受访者的表现

所以,我的疑问是:我应该在哪里保持业务逻辑?以下是 3种情况

1)在应用事件之前:做业务逻辑,然后应用(IntervieweeSelectedEvent),然后应用eventstore.save(intervieweeSelectedEvent)

2)在EventHandler内部:在EventHandler类中应用业务逻辑,例如handle(IntervieweeSelectedEvent受访者SelectedEvent),检查业务逻辑,然后更新ReadModel表中的对象状态。

3)在两个地方都应用业务逻辑,即在应用事件之前和处理事件时(结合1​​ + 2)

请在上面澄清我。

解决方法

事件源的主要问题是很难使用综合场景来产生可行的示例。

但我可能会提出一些比采访更好的建议。如果比较计算机前时代基于事件的系统,您会发现一个事件流是组成某个实体生命周期的事件存储,这是一件很长的事情。实体中的事件可能跨越几天(一个跟踪某些文档流的列表),一年(某个组织的会计期)或数十年(某个人的病历)的事件。

单个事件流通常代表一个实体-法律程序,分类帐或个人...每个事件都是对实体状态的交易性更改(如ACID)。

在您的情况下,这样的实体可以是职位。公开,宣布,受邀者邀请,接受邀请,评估技能,提出要约,接受要约,关闭职位。从我的头顶上。

将事件添加到实体时,表示实体的状态已更改。这是关于实体的新真理。您要注意更改真相。因此,这就是业务逻辑发生的地方。您运行一些业务逻辑来决定是否更改真相的决定。您决定更新真相的状态-保存事件。话虽如此,在这种情况下,“被访者被拒绝”是有效的事件。

由于事件持续存在,因此实体中所有保存的事件按照其各自的顺序无条件地成为有关实体真相的部分。然后,您不必决定是“接受”还是“拒绝”持续的事件,而仅决定其如何影响投影。

,

您标记了问题cqrs,但这实际上是示例中缺少的部分。

事件外包仅仅是一种查看对象当前状态的方法。您可以将该状态保存为现在显示的状态,或者从发生的一切中获取状态。 (例如,银行帐户当前的余额为所有交易的金额或总和)

因此,事件是发生的事情的“事实”。在您的情况下,那将是具有一定分数的面试。而且(取决于您的业务逻辑),如果障碍会随着时间而改变,它也可以声明状态。

关键点在于,您应始终遵循以下链条:

“命令被验证,如果通过则创建持久的不可更改事件”

这意味着在您的情况下,我将选择选项1。应验证SelectIntervieweeCommand,如果一切正常,请创建一个IntervieweeSelectedEvent,这是不可更改的事实。因此,无论受访者是否通过了业务逻辑,都必须驻留在命令处理程序函数中。

,

您应该能够从事件流中重建特定时间点的实体状态。

这意味着应用事件不应包含状态映射逻辑以外的任何逻辑。在这些事件中必须明确定义从事件中预测AR状态所需的所有状态。

事件是一种定义状态更改的表达方式,而不是操作/命令。例如,如果IntervieweeRejected的意思是IntervieweeStatusChanged(rejected),则含义永远不会改变。 IntervieweeRejected事件不能暗示除status = rejected以外的任何事物,除非事件数据中捕获了其他状态(例如原因)。

很显然,状态的表示方式总是可以改变的,但是含义不能改变。例如,AR可能仅通过投影当前状态开始,然后在投影整个状态历史记录时开始。

apply(IntervieweeRejected) => status = REJECTED //at first
apply(IntervieweeRejected) => statusHistory.add(REJECTED) //later

我有一个业务逻辑,即如果受访者的绩效

业务逻辑将放置在标准的公共AR方法中。在这种特定情况下,您可能期望interviewee.assessPerformance(POOR)产生IntervieweePerformanceAssessed(POOR)IntervieweeRejected事件。如果您以后需要重新评估该智能筛选政策(例如,如果已更改),则可以实施reevaluateSmartScreeningPolicy操作。

此外,请注意,此类逻辑甚至可能不属于Interviewee AR本身。智能筛选策略可能被视为在IntervieweePerformanceAssessed事件之后/响应事件发生的事件。此外,我可以轻松地看到由AI驱动的智能筛选策略如何变得非常复杂,可以证明它生活在专用的Screening受限环境中。

您的问题实际上使我考虑了如何有效地捕获上下文或事件发生的原因,我已经问过here:)