~TLDR:我正在为我的一个大型项目实施CQRS + DDD解决方案,而且,我想知道我的命令处理程序是否有任何真正的原因无法直接发送命令对象到我的聚合,在少数几种情况下,命令对象是数据丰富的?我无法找到任何具体的理由,为什么这会是任何一种反模式,我找不到任何关于这种类型设计的详细信息。
背景:之前我已经实施了CQRS系统,并且我已经实现了DDD应用程序,但在适当的Eric Evans样式域驱动的应用程序中从未实现过CQRS + DDD。所以我问,因为我不想滥用我的聚合物,并且长期伤害我的申请。
我的命令对象拥有相当多的数据的一个例子是注册命令,它接收8个以上的字段(名字,姓氏,首选名称,dob,标题,用户名,密码,部门等)。在我的Aggregate上创建一个有8个参数的方法,并且使用某种dto的替代解决方案,让我的处理程序将命令映射到dto - 要么自动使用automapper,要么是内联的 - 感觉非常尴尬似乎是不必要的非增值抽象。
我还可以看到未来的用例,其中命令可能是数据丰富的(它不会占很大比例的命令,但仍然会有一些),所以我希望看起来像这样从一开始就是正确的方面。
答案 0 :(得分:13)
命令对象通常以基本类型表示,而聚合方法签名将以域概念表示。
您没有立即认识到这一事实可能意味着您错过了很多机会在您的域中明确隐含概念。
“一个包含8个以上字段的注册命令(名字,姓氏, 首选名称,dob,标题,用户名,密码,部门等)“
有什么打击你的是firstname
和lastname
肯定会形成一个有意义的整体,例如new FullName(firstname, lastname)
而且我确信还有很多其他案例中的值对象(VO) )可以或应该在您的域中使用... Username
,Password
等?使用VO对一起变化的事物进行建模将更好地描述您的模型,并减少您必须传递的参数数量。
因此,这会使命令对象成为聚合方法参数的不良候选对象。如果你走这条路,你肯定会错过建模机会。
答案 1 :(得分:2)
同意@plalx。
获取命令作为聚合方法参数可能会导致聚合中包含过多的映射代码:将原始类型映射到域对象,最好放在域对象之外。
但对于更简单的项目,我认为这是一个好的开端。
在注册案例中,有界上下文通常是一个支持域,复杂性通常来自外部集成(电子邮件通知,社交帐户注册等)。在这种情况下,我认为有界上下文集成比内部模型更重要。因此,将命令作为聚合方法参数可以快速完成工作,并节省您专注于核心域的时间。