【发布时间】:2021-10-23 16:55:34
【问题描述】:
简单电子商店的典型示例。
假设用户将一些商品添加到购物篮并点击“结帐”。发出“创建订单”命令。现在,在实际创建状态为“Payment Expected”的订单记录和数据库中的相应订单行之前,我们必须检查用户选择的商品是否仍然可用(也许当用户将某些商品添加到购物篮时它们是可用的但不再)。而且我们还必须保留它们,这样它们就不会在用户还在结账时突然消失。
所以我的问题是如何执行这个“检查和保留”例程?在我看来,我有多种选择:
- 在“创建订单”命令处理程序中使用
ProductStockRepository保留产品,然后在成功使用OrderRepository创建订单。这意味着,我们在单个处理程序中使用多个存储库。 - 不要在“创建订单”处理程序中直接使用
ProductStockRepository,而是创建一个ProductStockService并调用其上的方法来检查和保留产品。我们仍然在单个处理程序中使用多个存储库,但库存存储库的使用是抽象的。 - 创建一个内部“Reserve Products”命令并从“Create Order”命令处理程序内部调度并等待它。
- “结帐”按钮发送“预订产品”命令而不是“创建订单”。在“保留产品”处理程序中,我们尝试保留产品并成功调用“保留产品”域事件。触发相应的事件处理程序,我们在其中创建一个订单。
- 其他方式?
这不是关于如何最好地为电子商店结账流程建模的问题。以上只是一个例子。我想在许多不同的应用程序中可能会有许多类似的场景。
【问题讨论】:
-
我知道您想要对您的场景进行回答,但我想指出,这不是简单的电子商店的运作方式。在成功下订单并付款之前,(几乎)从未保留库存。考虑到很大一部分在线支付失败。如果您保留库存(可能价值数千美元,具体取决于您出售的商品),您可能会因为库存不足而失去合法客户。此外,您的软件中的库存水平很可能不正确,因为仓库中的真实物品会丢失、损坏等,因此您无论如何都必须考虑下没有库存的订单。
-
我不是真的写网店,只是大家用的一个例子。我只是想问一个关于具体事物而不是抽象事物的问题。我真正的问题是是否可以在单个命令处理程序中使用多个存储库,或者您必须一直使用事件。我认为在这种情况下,使用事件没有意义,但我不断看到有关事件如何始终是可行的方法的帖子。
-
这不会回答您的问题,但它是一种启发式方法。事件溯源倾向于迫使周围的一切也使用事件溯源。诀窍是只在有意义的地方使用它,并在其他地方(例如经典的 DDD)使用更传统、更简单、易于进化的方法。除非您从一开始就拥有正确的聚合和事件集,否则事件溯源系统很难发展。如果有人正在重建 2/3 次相同的系统,则可能会出现这种情况。过去几年有一些论文证实了这一点,所以在使用 CQRS/ES 时请谨慎行事。
-
@Augusto 使用事件并不一定意味着使用事件溯源。我的看法是,大多数事件驱动架构不使用事件溯源,尽管我没有数据支持。
-
@FrancescCastells 你说的很对!我阅读了 CQRS 并假设它正在使用事件溯源。另一个例子说明假设有多糟糕:)