【问题标题】:Looping commands following an event using CQRS DDD使用 CQRS DDD 在事件之后循环命令
【发布时间】:2019-09-12 13:56:28
【问题描述】:

假设我想在删除社区时删除社区中的所有房屋(我真的在举一个随机的例子)。我想知道的是,在事件之后链接一组命令的最佳做法是什么:

1)

  • DeleteNeighborhoodCommand 从任何入口点发送
  • DeleteNeighborhoodCommandHandler 被触发,删除 Neighborhood 并调度 NeighborhoodDeletedEvent
  • 触发DelteHousesWhenNeighboorDeletedEventListener,查询相关小区所有房屋,并一一发送DeleteHouseCommand
  • DeleteHouseCommandHandler被多次触发,删除House并派发HouseDeleted事件

2)

  • DeleteNeighborhoodCommand 从任何入口点发送
  • DeleteNeighborhoodCommandHandler被触发,删除Neighborhood,删除每个房屋并发送NeighborhoodDeletedEvent和X次HouseDeleted

请务必注意,我们处于同一个限界上下文中,并且我们正在处理同一个域内的聚合。

【问题讨论】:

    标签: domain-driven-design cqrs


    【解决方案1】:

    我认为选项 1 是更好的选择,因为您在 NeighborhoodDeletedEvent 上触发了简单的脱节操作。

    在选项 2 中,您将硬链接其中一项操作(删除房屋)并引发不一定表示刚刚执行的命令的事件 (DeleteNeighborhoodCommand)。

    即使在同一个有界上下文中并处理同一个域中的聚合,恕我直言,这样保持异步和基于事件的方式对您有长期帮助,因为它鼓励明确的职责分离。没有一个命令比它应该处理的要多。

    【讨论】:

    • 感谢您的回复。如果聚合根边界定义了一致性边界,那是否意味着它们应该被封装在一起作为一个单独的操作?我觉得执行选项 1 可以增强最终的一致性,从而在解耦代码中获得少量收益。增益也是相对的,因为这意味着逻辑分布在不同的操作集上,但我想一切都是相对的。
    • 我假设 NeighborhoodHouse 是两个不同的聚合。如果它们是同一个聚合的一部分,那么是的,将事物作为一个事务的一部分进行更改是有意义的。当然,除非出于性能原因,您希望将某个操作设置为背景。但无论哪种方式,在玩长线游戏时,保持棋子解耦和小,这将有助于您在日益复杂的情况下保持敏捷和自信。
    【解决方案2】:

    嗯,这完全取决于您的型号。

    删除社区后是否需要强制删除所有房屋?您是否将邻域用作某些特定域进程的分组?换句话说,一个房子(不变量)是否必须有一个社区?

    我在想,也许你的房子不需要是 AR,而是居住在社区 AR 中的实体的集合。

    你看,DDD 是关于建模,而不是关于它周围的基础设施。一旦按照您想要的方式进行建模,其他部分就会自然而然地到位。

    假设它们是两个独立的 AR,我会发出一个事件 NeighborhoodDeleted,然后在事件处理程序中,我会简单地获取该社区的所有房屋并将它们从存储库中删除。这样,您就不需要仅仅因为您的社区有 200 座房屋就发出 200 条命令。

    但同样,您需要正确地为您的域建模。你永远不会第一次就做好,所以,不要压力太大。只是不断发展它。

    【讨论】:

      猜你喜欢
      • 2015-11-21
      • 2014-10-21
      • 1970-01-01
      • 2019-10-03
      • 1970-01-01
      • 2015-12-25
      • 1970-01-01
      • 1970-01-01
      • 2013-09-28
      相关资源
      最近更新 更多