6

我想在我的项目中使用 CQRS 模式的元素。我想知道我是否正确使用命令和事件。我不确定事件是否可以调用命令。为了更好地展示我想要做什么,我将使用图表和示例。

这是一个例子:

用户调用 TripCreateCommand。TripCreateCommandHandler 完成他的工作并在成功后发布 TripCreatedEvent。

现在我们有两个 TripCreatedEvent 的监听器(监听器执行的顺序无关紧要)

第一个监听器(可以在第二个监听器之后执行):

对于 trip.author.friends 中的每个用户调用两个命令(命令的顺序很重要)

  1. PublishTripOnUserWallCommand
  2. SendNewTripEmailNotificationCommand
  3. 发送NewTripPlatformNotification

第二个监听器(可以在第一个监听器之前执行):

  1. PublishTripOnUserSocials

这是示例图:

在此处输入图像描述

这是一个好方法吗?EventListener 可以调用命令吗,或者我应该以其他方式调用它吗?

4

2 回答 2

11

您的问题是关于与 CQRS 一起工作但与 CQRS 无关的消息驱动架构。

无论如何,您的图表几乎是正确的。事件订阅者/处理程序(我更喜欢这个术语)可以通过服务总线发送新命令,但这并不是您应该始终这样做的规则。我直接在事件处理程序中实现了很多功能,尽管发送新命令可能会更加干净和可靠。这真的取决于我想做什么。

请注意,消息处理程序(命令或事件)不应该知道其他处理程序。他们应该了解公共汽车并且公共汽车负责处理。这意味着在您的应用程序中,事件处理程序将总线作为依赖项,创建命令并通过总线发送。事件处理程序本身不知道是什么命令处理程序生成了事件并且可以“回复”它。

通常这些命​​令将被独立处理并且您不能保证顺序(除非它们被同步处理)所以也许您希望第二个命令作为第一个命令处理的结果发出。事实上,Saga 可能就是这种情况。

AFAIK 你只是在谈论同步做事,所以你的方法在这种情况下有效,但它可能不可扩展。转向异步处理会破坏这个执行流程。但是,您的应用程序可以使用它,并非所有内容都需要 twitter。

消息驱动的架构并不是那么简单,并且在某些情况下(例如您希望后端立即响应)实现起来相当复杂,至少比“标准”方法更复杂。因此,对于那些特殊情况,您可能希望以“旧”方式进行操作。

如果您担心解耦和测试,您仍然可以将服务设计为消息处理程序,但直接使用它们,而不是使用服务总线。

于 2014-01-20T20:27:00.787 回答
-2

不知道为什么需要命令来执行更新用户墙上的信息。为什么你会选择不使用 View Model Updater 来完成该任务。

发送电子邮件可以被视为一个命令,但也可以很容易地被视为只是另一个视图模型更新。

不清楚 SendNewTripPlatformNotification 的目的是什么,所以我不能在那里给出任何建议......

其中一些也可能是Saga的候选者。其次,我在图中缺少您的域,即应该负责发布任何事件,还是您认为 CommandHandler 是域?

于 2014-01-20T19:58:00.297 回答