CQRS 命令和查询。从 DDD 角度来看,它们属于应用程序级别还是域级别?

Jac*_*ian 9 domain-driven-design cqrs

在阅读不同的 DDD 文献时,我偶然发现了一个理论问题。问题是我是否应该将命令和查询放置在应用程序级别或域级别。

因此,像 Scott Wlaschin 这样的一些作者(在他的《Domain Modeling Made Functioning》一书中)说

如果命令成功,它将启动一个工作流程,进而创建相应的领域事​​件

因此,例如“下订单”命令和域事件“下订单”之间存在对应关系。这让我相信,我应该将命令和事件放在一个级别上并像这样组织它:

\Model
    \Message
         \Command
             PlaceOrder.lang
         \Event
             OrderPlaced.lang
Run Code Online (Sandbox Code Playgroud)

因此,我将所有命令放在域级别,而应用程序服务调用这些命令并将它们包装在事务中。

然而,Scott Millett 的书(领域驱动设计的模式、原则和实践)中表达了另一种观点。引用说:

命令是一项业务任务,是系统的一个用例,它位于应用程序层中。您应该使用业务语言编写命令。

由于这种矛盾,我不太确定处理命令(以及查询)的最规范的方式是什么。在现实世界中,它们存在于域级别还是应用程序级别?

Voi*_*son 1

由于这种矛盾,我不太确定处理命令(以及查询)的最规范的方式是什么。在现实世界中,它们存在于域级别还是应用程序级别?

文献在这一点上有点令人困惑,主要是由于历史的原因。

当我们谈论消息时,也就是我们的应用程序/服务的API;这些属于领域模型之外。

根本问题是消息模式是您的应用程序和与之通信的客户端之间合同定义的一部分。合同,尤其是那些跨越组织边界的合同,需要保持稳定,因为变更的成本很高。

将此与域模型的内存表示进行对比,后者纯粹是实现细节,可以随时更改。您的数据模型处于中间位置 - 客户并不关心您的信息在持久存储中是什么样子,但您未来的应用程序需要能够读取前身留下的信息。

Udi Dahan说服务“共享契约和模式,而不是类或类型”时,他描述的是正在交换的消息。客户端不需要关心我们在域模型的实现中使用什么“类或类型”。

现在,公平地说,客户也不需要关心我们在应用程序的实现中使用什么“类或类型” 。事实上,您采用 PlaceOrder消息(通过网络上发送给您的字节序列表示的语义)并将其表示为类型化内存引用的内存中排列,这是您自己的事情。

这里我们要注意的是,负责解释字节的代码属于负责与其他事物通信的代码部分,而不是管理业务的内存抽象的代码部分。