【问题标题】:CQRS to command or not to, that is the questionCQRS 指挥还是不指挥,这是个问题
【发布时间】:2020-06-07 08:54:03
【问题描述】:

我是 CQRS 的新手,但可以看到其中的价值,因此我试图将其应用于我们正忙于重建的金融系统。

就像我提到的,这是一个基本的金融系统,具有基本的余额、提款、存款等功能。

我有一个提款和存款命令。但我正在努力平衡。

根据领域专家的说法,他们希望代表客户将余额作为交易来处理,(目前)还没有财务影响。因此,当客户端通过设备进行余额查询时,它会创建一个事务,同时也会创建一个余额查询。

在 CQRS 世界中,您可以区分改变状态和查询的命令,以及以某种方式检索数据的命令。

抱歉,如果我在这里的理解有缺陷。有人能指出我正确的方向吗?

编辑: 也许让我这样说吧。我正在考虑创建一个 CheckBalanceCommand 来创建交易并将 BalanceCheckedEvent 插入商店。但是我还需要创建一个 CheckBalanceQuery 来从读取的数据库中检索实际余额。 为了满足余额请求,我需要调用两者。

【问题讨论】:

    标签: domain-driven-design cqrs


    【解决方案1】:

    这是一个有趣的问题。您的业​​务案例是有效的:一些命令不会改变聚合/实体状态,仍然处理它们并且它们产生的事件很重要(例如,用于审计跟踪)。

    为了支持这些情况,我将引入一个名为 IdentityEvent 的基本事件类型(受各种数学运算符的标识值的启发,并作为该概念的证明;在某个值上操作它们不会改变它)。在发出相应的命令时,此事件的派生类(例如您的情况下为 BalanceCheckedEvent)将被附加到聚合的事件流中,并且视图投影可以像往常一样从它们构造视图;但是,他们的 mutate 方法在从事件流重构实体时不会执行任何实际的变异。

    实际的命令处理发生在领域层。您的一些应用服务,在应用层,接收查询请求,像往常一样处理它。此外,在查询操作之前或之后,同一应用程序服务可能会在聚合根本身上向域层发出命令。这并不违反任何原则:您的读取和查询模型仍然是分开的,应用程序服务只是在两者之间进行协调。

    【讨论】:

      【解决方案2】:

      这并不像您想象的那么罕见。另一个有效的商业案例是服务提供商对某人进行信用检查。信用报告公司实际上存储了针对信用评分的查询,并使用它来影响未来的信用评分。当然,当我说这并不像我们想象的那么罕见时,我并不是在试图规范这种做法(我们应该回过头来了解这样的东西为我们的产品提供的真正价值)。

      我的建议是明确地对此进行建模,而不是试图概括这一点。此功能可能是由某些业务需求驱动的,您应该对其进行建模。我的意思是你应该将服务读取的服务完全视为一个单独的服务,它可以为已经发生的事情引发它自己的事件,并以反应方式设计系统的其余部分(即响应另一个生成的事件BC/服务)。

      例如,您可以让为查询提供服务的服务触发 BalanceChecked 事件,同一服务或另一个服务可以将其存储在流中以供后续处理。

      我不建议使用命令,因为如果您要回复数据,就好像有人可以拒绝该命令;已经发生了,有人已经掌握了数据。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-05-31
        • 1970-01-01
        • 1970-01-01
        • 2018-06-22
        • 2010-11-24
        • 2011-01-21
        • 2013-11-11
        相关资源
        最近更新 更多