【问题标题】:Should I use Command to implement a domain derivations in CQRS我应该使用命令在 CQRS 中实现域派生吗
【发布时间】:2013-09-23 08:22:27
【问题描述】:

我在机票预订应用程序中使用 CQRS。一个用例是帮助客户取消他们的票。但在实际取消之前,客户想知道罚款。

罚款是根据空气规则计算的。我们的一些提供商可以通过暴露 Web 服务来计算惩罚,而其他提供商则不会。 (他们发表了一些解释算法的论文)。所以我定义了一个域服务

public interface AirTicketService {
     //ticket demand method

     MonetaryAmount penalty(String ticketNumber);

     void cancel(String ticketNumber, MonetaryAmount penalty);
}

我的问题是哪一方(命令/查询)负责调用此域服务并在 CQRS 样式应用程序中返回结果?

我想用一个命令:CalculatePenlatyCommand,这样,很容易复用领域模型,但是有点奇怪,因为这个命令不修改状态。

或者如果这是一个查询,我应该检索票的读取模型吗?但是命令端和查询端都需要相同的 DomainService,这也很奇怪。

域派生是查询吗?

【问题讨论】:

    标签: domain-driven-design cqrs event-sourcing axon


    【解决方案1】:

    无需将所有内容都硬塞到命令查询管道中。您可以独立于 UI 查询此服务,而无需发出命令或询问读取模型。

    【讨论】:

    • penalty() 中的 arg 需要我们的提供商提供的 ticketNumber,我将此值存储在 AirReservation 聚合和 AirReservation 读取模型中。因此,在调用服务之前,我需要从存储库中检索域模型或查询 readmodel。但我会考虑你的建议和 +1 的回应和“鞋拔”:)
    • 我明白了。在这种情况下,您应该从读取模型中获取票号,然后查询 AirTicketService。
    【解决方案2】:

    如果现有模型“符合”该模型的术语和结构,那么使用现有模型满足查询并没有错。无需为此目的建立单独的读取模型。这并非没有风险,因为查询的语义和上下文应该与仅用于写入目的的模型密切相关。我提到的风险是写入和读取问题可能会分开(我们回到第一方,即人们首先选择 CQRS 的原因)。因此,随着新要求的出现,您必须保持关注。

    非常适合此模型的查询是我所说的“模拟器”,您希望在其中使用当前状态运行模拟,例如向最终用户提供反馈。在不止一次的情况下,我发现模拟逻辑既可以用作反馈机制,也可以用作(写入操作/命令的)转向机制的执行。不同之处在于我们对模拟结果的处理方式。同样,这并非没有风险,需要仔细判断。

    【讨论】:

      【解决方案3】:

      你可能会提出Calculate Penalty Command一点都不奇怪的论点。 用户要求系统做某事——命令就够了。

      您甚至可以在您的域中设置Penalty Calculation Requested Event 事件,并且感觉正确。因为,在某些时候,您可能对 不确定 客户、想要取消票但他们每次都改变主意的客户感兴趣等。计算也可能是异步执行的 - 你之后可以通过各种方式向用户提供结果(惩罚成本)...

      或者,以其他方式:在您的ticket预订活动中,商店取消罚款也是如此。然后,您可以随时获取该值,而无需重新计算它......但这可能是错误的(?)因为惩罚很大程度上取决于时间,对(您取消机票的时间越晚,您支付的费用越多) ?

      如果这一切都需要过度复杂化等,那么我想我也同意rmac's answer :)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-26
        • 1970-01-01
        • 2016-08-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多