domain-driven-design - CQRS-命令是否应尝试创建 “complex”主从实体?

标签 domain-driven-design cqrs

我一直在阅读格雷格·杨(Greg Young)和乌迪·达汉(Udi Dahan)关于“命令查询责任分离”的思想,我读到的很多内容都引起了我的共鸣。我的域(我们跟踪正在运送的车辆)的概念是包含一个或多个停靠点的路线。我需要我的客户能够通过调用Web服务在我们的系统中进行设置,然后能够检索有关路线以及车辆行驶方式的信息。

过去,我会“缩减” DTO类,这些类与我的域类非常相似,而客户会创建一个带有StopDto数组的RouteDto,然后调用我们的CreateRoute网络方法,并传入RouteDto。当他们通过调用GetRouteDetails方法查询我们的系统时,我将向他们返回完全相同的对象。 CQRS的吸引人的方面之一是RouteDto可能具有客户想要查询的所有属性,但是在创建Route时没有业务设置。因此,我创建了一个单独的CreateRouteRequest类,该类在调用CreateRoute“命令”时传递给它,还有一个Route DTO类,该类作为查询结果返回。

class Route{
    string Reference;
    List<Stop> Stops;
}

但是我需要我的客户在创建路线时向我提供“路线和停靠点”详细信息。如我所见,我可以...

给我的CreateRouteRequest类一个Stops(s)属性,它是一个“东西”数组,表示他们需要提供的有关每个停靠点的数据-但是我怎么称呼此类?这不是停靠点,因为这就是我在Route DTO中调用的DTO列表,但是我不喜欢“CreateStopRequest”。我还想知道我是否陷入了CRUD的思维定势中,就主从信息进行思考,并要求客户也这样思考。
class CreateRouteRequest{
    string Reference;
    ...
    List<CreateStopRequest> Stops;
}

或者

他们调用CreateRoute,然后多次调用AddStopToRoute方法。这感觉有点“行为”,但是我将失去将创建包含停靠点的路线作为单个原子命令对待的能力。如果他们创建路线,然后尝试添加由于某些验证问题而失败的Stop,则他们将拥有部分正确的Route。

我无法为在选项1中使用的“StopCreationData”对象列表起一个好名字,这一事实使我想知道是否缺少某些东西。

最佳答案

我意识到这是一个非常老的帖子,但是最近我一直在努力寻找一些类似的模式,并感到有必要为该主题做贡献。我认为,导致OP感到脱节的一件事是,他们正在将域术语塞入自己的操作语言中,而不是将其设计与域保持一致。

技巧是将“create”用作动词。我发现,“创建”在开发人员的头脑中与“插入”相同(请考虑“CRUD”),并且当我们开始尝试DDD时,我们常常会动用该动词,因为它似乎技术性较差。不过,此处“创建”的路由已经存在。它们仅被记录在系统中。同样,路线上的停靠点已经存在,但也正在记录中。对感知和措辞的简单更改,也许通过将RecordRouteCommand与一个可选的随附RecordStopOnRouteCommand集合一起使用,可能会解决一些困惑。允许停止记录命令也可以独立发送,这将在构造上提供更大的灵活性并增强API。

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

关于domain-driven-design - CQRS-命令是否应尝试创建 “complex”主从实体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3054774/

相关文章:

rabbitmq - 是否有一些指导方针来识别 DDD 中有界上下文的 RabbitMQ 队列

c# - 通用存储库模式 - DDD 实现

c# - 长时间运行的有状态 'services' 适合 DDD 的什么地方?

c# - 查询重复聚合根属性的写入模型

domain-driven-design - DDD 中两个限界上下文之间的通信

domain-driven-design - 处理跨聚合关系中的事件和聚合状态

domain-driven-design - 偶尔连接CQRS系统

design-patterns - 具有实体树的域聚合根

model-view-controller - 关于 DDD 结构和分层。

architecture - 更新 CQRS 中的查询部分