2

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

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

public interface AirTicketService {
     //ticket demand method

     MonetaryAmount penalty(String ticketNumber);

     void cancel(String ticketNumber, MonetaryAmount penalty);
}

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

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

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

域派生是查询吗?

4

3 回答 3

1

您可能会提出“计算惩罚命令”一点也不奇怪的论点。用户要求系统做某事——命令足够了。

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

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

如果所有这些都需要过度复杂化等,那么我想我也同意rmac 的回答:)

于 2014-01-03T21:05:31.123 回答
1

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

于 2013-09-23T08:36:02.537 回答
1

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

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

于 2013-09-24T11:50:40.260 回答