将 CQRS 命令直接传递给域对象
Passing CQRS commands directly to Domain objects
~TLDR:我正在为我的一个大型项目实施 CQRS + DDD 解决方案,而且我想知道是否有任何真正的原因导致我的命令处理程序无法直接将命令对象分派到我的聚合,在少数情况下,命令对象的数据丰富?我找不到任何具体原因说明这会成为任何类型的反模式,而且我找不到任何关于此类设计的详细信息。
背景:我以前实现过 CQRS 系统,也实现过 DDD 应用程序,但从未在适当的 Eric Evans 风格域驱动应用程序中实现 CQRS + DDD。所以我问是因为我不想滥用我的聚合,并从长远来看伤害我的应用程序。
我的命令对象的一个例子有相当多的数据是一个注册命令,它包含 8 个以上的字段(名字、姓氏、首选名称、出生日期、职位、用户名、密码、部门等)。在我的聚合上创建一个具有 8 个参数的方法感觉非常尴尬,以及使用某种 dto 的替代解决方案,并让我的处理程序将命令映射到 dto - 自动使用 automapper 或内联 - 似乎是不必要的和非增值抽象。
我还可以看到未来的用例,其中命令可能包含丰富的数据(命令的比例不会很大,但仍然会有一些),所以我想了解这个看似微不足道的方面从一开始就正确。
命令对象通常以原始类型表示,而聚合方法签名将以领域概念表示。
您没有立即意识到这一点可能意味着您错过了很多在您的领域中使隐含概念明确化的机会。
"a registration command that takes in 8+ fields (firstname, lastname,
preferred name, dob, title, username, password, department etc)"
应该让您印象深刻的是 firstname
和 lastname
绝对可以形成一个有意义的整体,例如 new FullName(firstname, lastname)
我敢肯定还有很多其他情况需要值对象(VO) 可以或应该在您的域中使用... Username
、Password
等?使用 VO 对一起变化的事物建模将更好地描述您的模型并减少您必须传递的参数数量。
因此,这使得命令对象成为聚合方法参数的不佳候选者。如果你走那条路,你肯定会错过做模特的机会。
同意@plalx。
将命令作为聚合方法参数可能会导致聚合内部映射代码过多:将原始类型映射到领域对象,最好放在领域对象之外。
但对于更简单的项目,我认为它是一个很好的入门者。
在注册案例中,限界上下文通常是支持域,复杂性通常来自外部集成(电子邮件通知、注册社交帐户等)。在这种情况下,我认为有界上下文集成比里面的模型更重要。因此,将命令作为聚合方法参数可能是完成任务的快速开始,并节省您专注于核心领域的时间。
~TLDR:我正在为我的一个大型项目实施 CQRS + DDD 解决方案,而且我想知道是否有任何真正的原因导致我的命令处理程序无法直接将命令对象分派到我的聚合,在少数情况下,命令对象的数据丰富?我找不到任何具体原因说明这会成为任何类型的反模式,而且我找不到任何关于此类设计的详细信息。
背景:我以前实现过 CQRS 系统,也实现过 DDD 应用程序,但从未在适当的 Eric Evans 风格域驱动应用程序中实现 CQRS + DDD。所以我问是因为我不想滥用我的聚合,并从长远来看伤害我的应用程序。
我的命令对象的一个例子有相当多的数据是一个注册命令,它包含 8 个以上的字段(名字、姓氏、首选名称、出生日期、职位、用户名、密码、部门等)。在我的聚合上创建一个具有 8 个参数的方法感觉非常尴尬,以及使用某种 dto 的替代解决方案,并让我的处理程序将命令映射到 dto - 自动使用 automapper 或内联 - 似乎是不必要的和非增值抽象。
我还可以看到未来的用例,其中命令可能包含丰富的数据(命令的比例不会很大,但仍然会有一些),所以我想了解这个看似微不足道的方面从一开始就正确。
命令对象通常以原始类型表示,而聚合方法签名将以领域概念表示。
您没有立即意识到这一点可能意味着您错过了很多在您的领域中使隐含概念明确化的机会。
"a registration command that takes in 8+ fields (firstname, lastname, preferred name, dob, title, username, password, department etc)"
应该让您印象深刻的是 firstname
和 lastname
绝对可以形成一个有意义的整体,例如 new FullName(firstname, lastname)
我敢肯定还有很多其他情况需要值对象(VO) 可以或应该在您的域中使用... Username
、Password
等?使用 VO 对一起变化的事物建模将更好地描述您的模型并减少您必须传递的参数数量。
因此,这使得命令对象成为聚合方法参数的不佳候选者。如果你走那条路,你肯定会错过做模特的机会。
同意@plalx。
将命令作为聚合方法参数可能会导致聚合内部映射代码过多:将原始类型映射到领域对象,最好放在领域对象之外。
但对于更简单的项目,我认为它是一个很好的入门者。
在注册案例中,限界上下文通常是支持域,复杂性通常来自外部集成(电子邮件通知、注册社交帐户等)。在这种情况下,我认为有界上下文集成比里面的模型更重要。因此,将命令作为聚合方法参数可能是完成任务的快速开始,并节省您专注于核心领域的时间。