在过去,我会“删减”与我的域类非常相似的DTO类,客户会创建一个带有StopDto数组的RouteDto,并调用我们的CreateRoute web方法,传递RouteDto.当他们通过调用GetRouteDetails方法查询我们的系统时,我会向它们返回完全相同的对象. CQRS的一个吸引人的方面是RouteDto可能具有客户想要查询的所有属性,但在创建Route时没有业务设置.所以我创建了一个单独的CreateRouteRequest类,它在调用CreateRoute“命令”时传入,而一个Route DTO类作为查询结果返回.
class Route{ string Reference; List<Stop> Stops; }
但是我需要我的客户在创建路线时为我提供路线和停止详细信息.我看到它可以……
给我的CreateRouteRequest类一个Stops(s)属性,这是一个“某事”数组,表示他们需要提供的关于每个停止的数据 – 但是我该怎么称呼这个类?这不是一个Stop,因为我在Route DTO中调用了DTO列表,但我不喜欢“CreateStopRequest”.我也想知道我是否陷入了一种CRUD心态,在这里思考主要细节信息并要求客户也这样思考.
class CreateRouteRequest{ string Reference; ... List<CreateStopRequest> Stops; }
要么
他们调用CreateRoute,然后对AddStopToRoute方法进行多次调用.这感觉更“行为”,但我将失去处理创建路线的能力,包括其作为单个原子命令的停止.如果他们创建了一个Route然后尝试添加一个由于某些验证问题而失败的Stop,那么他们将会有一个部分正确的Route.
事实上,我不能为我在选项1中使用的“StopCreationData”对象列表提供一个好名字,这让我想知道是否有我遗漏的东西.
解决方法
提示是使用“创建”作为动词.我发现,“创造”与开发者脑中的“插入”相同(想想“CRUD”),当我们第一次开始尝试使用DDD时,我们常常使用该动词,因为它似乎不那么技术性.但是,这里“创建”的路线已经存在.它们仅仅被记录在系统中.沿着相同的路线,路线上的站点已经存在,但也被记录下来.感知和措辞的简单改变,可能是通过使用RecordRouteCommand和RecordStopOnRouteCommand的可选附带集合,可能已经解决了一些混乱.允许独立发送停止记录命令将提供更多的构造灵活性并加强API.
我也同意Szymon关于请求与命令的关系.这种措辞也会导致思考与cqrs方法相反.如果DDD告诉我一件事,那就是我们在项目中使用的词语并不重要,它们至关重要.