5

我想使用 Axon 框架实现 CQRS 和 ES

我有一个非常复杂的 HTML 表单,它代表了包含六个步骤的招聘流程。
ES 将有助于生成选定日期的历史统计数据并跟踪形式的变化。

管理员始终可以执行多项操作:

  • 指定负责每个步骤的人员
  • 为每个步骤提供注释
  • 每一步都接受或拒绝候选人
  • 打开/关闭短信或电子邮件通知
  • 分配标签

表单更新(仅区别)从 UI 应用程序发送到后端。

假设我只想对服务器端应用程序进行更改,问题是什么应该是命令,什么应该是事件,我考虑三个选项:


  1. 表单补丁是一个生成的命令Form Update Event

    • 该解决方案的缺点是每个事件处理程序都需要检查表单中的更改是否引用了此处理程序 ex。如果应该发送关于拒绝的电子邮件

  1. 表单补丁是一个生成多个事件的命令,例如:。Interviewer Assigned, Notifications Turned Off,Rejected on technical interview

    • 该解决方案的缺点是可能会生成一些事件,而其他事件则不会因为打破约束例如:Notifications Turned Off将成功但Interviewer Assigned由于分配未经授权的用户而失败。也许我应该在命令生成之前检查所有约束?

  1. 表单补丁转换为几个命令 ex: Assign InterviewerTurn Off Notifications每个命令生成事件 ex:Interviewer Assigned, Notifications Turned Off

    • 此解决方案的缺点是某些命令可能会失败,例如:Assign Interviewer可能由于分配未经授权的用户而失败。这将导致状态不一致,因为有些事件将存储在存储库中,有些则不会。也许我应该在命令生成之前检查所有约束?
4

3 回答 3

4

我要提请您注意的问题是:您是在为您存储的信息创建权限,还是只是在跟踪来自外部世界的信息?

乌迪·达汉(Udi Dahan)写了种族条件不存在;提出这个有趣的观点

时间上的微秒差异不应该对核心业务行为产生影响。

如果您的系统中有未经授权的用户,那么在他们被分配对特定步骤的责任之前获得授权对企业来说真的很重要吗?系统真的能判断出“错误”是责任分配给了错误的用户,而不是用户没有被错误地授权吗?

Greg Young 谈到了仓库系统中的异常报告,指出在这种情况下模型的职责不是防止数据更改,而是在数据更改产生不一致状态时进行报告。

如果您仍然更新数据,企业的成本是多少?

如果消息的语义是 aDecision Has Been Made或 that Something In The Real World Has Changed,那么您的模型不应该试图阻止该信息被记录。

FormUpdated由于您提到的原因,这不是一个特别令人满意的事件;您必须做很多额外的工作才能将其转换为特定领域的术语。如果有选择,您宁愿这样做一次。随着您的进行,将事件从与领域无关的形式转换为特定领域的形式是合理的。

HttpRequestReceived ->
FormSubmitted ->
InterviewerAssigned

其中中间表示是短暂的。

于 2018-03-09T03:48:59.513 回答
3

我可以看到第一个选项的一个很大的缺点。CQRS/ES 与 Axon 的最大优势之一是可扩展性。我们可以添加新功能而不必担心回归错误。添加新功能是为它们定义新命令、事件和处理程序的结果。它们中的任何一个都不应该与我们系统中存在的那些迭代。

FormUpdate 作为命令需要在其中一个处理程序中添加额外的逻辑。将新属性添加到补丁并因此添加到命令将导致当前逻辑发生变化。在这种情况下,可扩展性不再是优势。

于 2018-03-09T09:06:52.430 回答
1

VoiceOfUnreason 给出了一个很好的解释,当你开始使用这样的系统时,你应该考虑什么,所以一定要看看他的答案。

我唯一想补充的是,我建议您采用第三个选项。通过您提供的示例,更通用的命令/事件并不能说明您的域中发生的事情。更精细的事件可以更好地解释到底发生了什么,因为事件消息的名称已经指出了这一点。

将 Axon 框架拉入循环中,我还可以添加几个指针。从命令消息的角度来看,只走一条路线而不想太多是安全的。该框架很容易让您稍后调整命令结构。在 Axon Framework 培训中,通常建议让命令消息采用您正在执行的特定操作的形式。因此,'将一个人分配给一个步骤通常是 ' AssignPersonToStepCommand,因为这是您希望系统执行的确切操作。

从事件中,稍后决定您想要细粒度或通用事件通常有点麻烦。这源于进行事件溯源。由于事件是您的事实来源,因此您需要处理系统中所有形式的事件。

因此,我认为您的决定的重要性应该在于您的事件变得多么精细。回到您的问题:在您给出的示例中,我会说选项 3 最适合。

于 2018-03-09T07:45:49.753 回答