domain-driven-design - DDD 和 CQRS : use multiple r

简单电子商店的典型示例。

假设用户将一些商品添加到购物车并点击“结帐”。发出“创建订单”命令。现在,在实际创建状态为“预期付款”的订单记录和数据库中相应的订单行之前,我们必须检查用户选择的商品是否仍然可用(当用户将它们添加到购物车时,可能有些商品可用但现在不是了)。而且我们还必须保留它们,这样它们就不会在用户还在结帐时突然消失。

所以我的问题是如何执行这个“检查和保留”程序?在我看来,我有多种选择:

  • 在“创建订单”命令处理程序中,使用 ProductStockRepository 保留产品,然后在成功时使用 OrderRepository 创建订单。也就是说,我们在单个处理程序中使用多个存储库。
  • 不要在“创建订单”处理程序中直接使用 ProductStockRepository,而是创建一个 ProductStockService 并调用其上的方法来检查和保留产品。我们仍然在单个处理程序中使用多个存储库,但对库存存储库的使用进行了抽象。
  • 创建一个内部“Reserve Products”命令并从“Create Order”命令处理程序内部调度和等待它。
  • “Checkout”按钮发送“Reserve Products”命令而不是“Create Order”。在“Reserve Products”处理程序中,我们尝试保留产品并在成功时调用“Products Reserved”域事件。相应的事件处理程序会触发,我们会在其中创建一个订单。
  • 其他方式?

这不是关于如何最好地模拟电子商店结账流程的问题。以上只是一个例子。我想在许多不同的应用程序中可能会有许多类似的场景。

最佳答案

您提出的问题的解决方案与编码“风格”或遵循良好的 DDD 实践无关。如果在单个处理程序中使用多个存储库解决了您的问题,我相信您应该将其视为一个不错的选择。

但这种情况下的主要问题是,在许多系统中,订单和库存位于不同的服务/限界上下文中,因此位于不同的数据库中。库存甚至可能位于不受您控制的外部系统中。这意味着您无法保留库存并以交易方式下订单,因此您可能会保留库存而不下订单,反之亦然。

之所以建议使用事件来处理这些场景,是因为使用事件可以可靠地开发这种类型的工作流,尽管这会带来新的复杂性。通过一些技术,可以可靠地保留库存并发布一个事件,另一方面,可靠地捕获付款并发布另一个事件,然后下订单并发布另一个事件等。这个工作流程可能涉及诸如发件箱模式、重试、sagas、补偿操作(在一个步骤失败的情况下回滚之前的步骤)等。

关于domain-driven-design - DDD 和 CQRS : use multiple repositories from a single command handler?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69690198/

相关文章:

r - 使用 dplyr 获取术语列表、分组依据和汇总值

javascript - 如何将字符串javascript类型的两位小数相乘

javascript - typescript :如何定义具有许多未知键的对象

javascript - 如何在 Electron 15 中导入菜单

lua - 波浪号本身在 Lua 中是什么意思?

haskell - 不同类型的重载/多态函数

java - org.gradle.api.internal.tasks.testing.TestS

r - 在 download.file 中关闭 SSL 验证

spring-boot - 应用程序通过 Spring Boot Run 而不是通过 Intelli

r - 如何调整饼图上的 ggrepel 标签?