Domain driven design CQRS-命令是否应尝试创建一个;复杂的;主细节实体?

Domain driven design CQRS-命令是否应尝试创建一个;复杂的;主细节实体?,domain-driven-design,cqrs,Domain Driven Design,Cqrs,我一直在读Greg Young和Udi Dahan关于命令查询责任分离的思想,我读到的很多东西都引起了我的共鸣。我的领域(我们跟踪运送车辆)具有包含一个或多个站点的路线概念。我需要我的客户能够通过调用Web服务在我们的系统中设置这些,然后能够检索有关路线和车辆运行情况的信息 在过去,我会“削减”与我的域类非常相似的DTO类,客户会使用StopDto数组创建RouteDto,并调用我们的CreateRoute webmethod,传入RouteDto。当他们通过调用GetRouteDetails方

我一直在读Greg Young和Udi Dahan关于命令查询责任分离的思想,我读到的很多东西都引起了我的共鸣。我的领域(我们跟踪运送车辆)具有包含一个或多个站点的路线概念。我需要我的客户能够通过调用Web服务在我们的系统中设置这些,然后能够检索有关路线和车辆运行情况的信息

在过去,我会“削减”与我的域类非常相似的DTO类,客户会使用StopDto数组创建RouteDto,并调用我们的CreateRoute webmethod,传入RouteDto。当他们通过调用GetRouteDetails方法查询我们的系统时,我会将完全相同的对象返回给他们。CQR吸引人的一个方面是RouteDto可能具有客户想要查询的所有类型的属性,但在创建路由时没有业务设置。因此,我创建了一个单独的CreateRouteRequest类,在调用CreateRoute“command”时传入该类,以及一个Route DTO类,该类作为查询结果返回

class Route{
    string Reference;
    List<Stop> Stops;
}
类路由{
字符串引用;
列出站点;
}
但我需要我的客户在创建路线时向我提供路线和站点详细信息。在我看来,我也可以

给我的CreateRouteRequest类一个Stops(s)属性,它是一个“something”数组,表示它们需要提供的关于每个stop的数据——但是我怎么称呼这个类呢?这不是一个站点,因为这是我在路径DTO中调用的DTO列表,但我不喜欢“CreateStopRequest”。我还想知道,在这里,我是否陷入了一种积重难返的心态,从掌握详细信息的角度思考,并要求客户也这样思考

class CreateRouteRequest{
    string Reference;
    ...
    List<CreateStopRequest> Stops;
}
类CreateRouteRequest{
字符串引用;
...
列出站点;
}

他们调用CreateRoute,然后多次调用AddStopToRoute方法。这感觉有点“行为”,但我将失去将创建路线(包括其站点)视为单个原子命令的能力。如果他们创建一条路线,然后尝试添加一个由于验证问题而失败的站点,那么他们将拥有一条部分正确的路线


我无法为选项1中使用的“StopCreationData”对象列表找到一个好名字,这让我想知道我是否遗漏了什么。

我不认为您遗漏了什么

class CreateRouteRequest{
    string Reference;
    ...
    List<CreateStopRequest> Stops;
}
类CreateRouteRequest{
字符串引用;
...
列出站点;
}

我看起来不错。在我看来,使用AddStopToRoute的替代方案不是一个好主意,因为它创建了太多的“聊天”接口,无法有效地远程调用

但是,您使用CreateRoute*请求*似乎表明您正在使用请求/响应模式

如果您确实在向服务器发送命令,则服务器不应返回响应对象/消息。您可以让您的服务公开一个ExecuteCommand方法,并调用该方法,传递您的CreateRouteCommand


请求/响应不是正确的CQS IMHO。

我意识到这是一篇非常古老的帖子,但我最近一直在尝试一些类似的模式,我觉得有必要为这篇帖子做出贡献。我认为,导致OPs产生脱节感的一个原因是,他们将领域术语硬塞进了自己的操作语言中,而不是使他们的设计符合领域

提示是使用“create”作为动词。我发现,“Create”与开发人员心目中的“insert”(想想“CRUD”)是一样的,当我们第一次开始尝试DDD时,我们经常使用这个动词,因为它看起来不那么专业。不过,此处“创建”的路由已经存在。它们只是被记录在系统中。在同一条线路上,路线上的站点已经存在,但也正在被记录。在观念和措辞上做一个简单的改变,也许通过使用RecordRouteCommand和可选的RecordStopOnRouteCommand附带集合,可能会稍微解决混淆问题。允许独立发送停止记录命令也将在构造中提供更大的灵活性并加强API

我也同意Szymon关于请求与命令的观点。这种措辞也会导致与cqrs方法相反的想法。如果说DDD教会了我一件事,那就是我们在项目中使用的词语不仅重要,而且至关重要