Domain driven design 如何使用CQR从后端的业务域模型到前端公开只读计算?读模型与写模型问题

Domain driven design 如何使用CQR从后端的业务域模型到前端公开只读计算?读模型与写模型问题,domain-driven-design,cqrs,business-logic,Domain Driven Design,Cqrs,Business Logic,我有两个关于CQR和领域驱动设计(DDD)的问题 就我所理解的CQR背后的隔离思想而言,一个将有两个独立的模型,一个读模型和一个写模型。只有写模型可以通过命令访问和使用业务域模型。然而,read模型通过查询直接将数据库内容转换为dto,并且根本无法访问业务域 上下文:我正在编写一个web应用程序后端,为粒子物理提供计算服务。现在我的问题是: 1.)我的业务领域逻辑包含一些函数,这些函数计算数学值作为给定测量系统配置的输出作为输入。因此,从技术上讲,这些是只读查询,可以动态计算值,并且不会更改任何

我有两个关于CQR和领域驱动设计(DDD)的问题

就我所理解的CQR背后的隔离思想而言,一个将有两个独立的模型,一个读模型和一个写模型。只有写模型可以通过命令访问和使用业务域模型。然而,read模型通过查询直接将数据库内容转换为dto,并且根本无法访问业务域

上下文:我正在编写一个web应用程序后端,为粒子物理提供计算服务。现在我的问题是:

1.)我的业务领域逻辑包含一些函数,这些函数计算数学值作为给定测量系统配置的输出作为输入。因此,从技术上讲,这些是只读查询,可以动态计算值,并且不会更改任何模型中的任何状态。因此,它们应该是读取模型的一部分。但是,由于这些函数与域密切相关,它们必须是域模型的一部分,而域模型又是写模型的一部分。 当包含所有查询的read模型没有访问域模型的权限时,如何通过API使这些计算函数可用于前端

我真的需要触发一个命令来将所有计算保存到数据库中,以便读取模型可以访问计算结果吗?这些“一次性”计算只会被前端短期使用,以后没有人需要访问持久的计算结果。 测量配置必须是持久的,而不是计算结果。每当用户点击前端的“计算”按钮时,这些将被重新计算多次

2.)我还觉得我复制了很多数据验证代码,因为读模型和写模型都必须反序列化和验证流程链中相同或非常相似的请求参数
http请求体->json->未验证的DTO->验证值->命令/查询。
我该怎么处理呢?我可以在读模型和写模型之间共享验证代码吗?这似乎消除了种族隔离


提前感谢您的帮助和想法。

我认为您拥有的是一组域服务,它们通过给定的输入返回输出。 正如您所说,这些服务位于域中。但是,没有什么可以拒绝您在读取模型中使用它们。只要不更改函数内部的域,就可以在域上方的任何层中使用它们。 如果出于任何原因,此解决方案不可行,例如,因为服务需要无法/不希望在查询端构建的域对象,则始终可以将域服务包装在应用程序服务中。在这里输入一个基本对象,对域对象进行所有转换,调用域服务并返回结果值

对于第二个问题,您可以在域层中构建一个验证服务,作为一组服务或简单函数。同样,没有任何东西会拒绝您在验证步骤中使用它们。 我在上一个web应用程序中也做了同样的操作:表单数据的验证步骤调用一组域服务,在处理命令期间构建域对象时也会使用这些服务。更改域中的验证具有与Web相关的验证更改相同的效果。您验证了两次(在生成命令之前和在生成域对象期间),但都没有问题


看看端口/适配器或洋葱架构:它有助于理解层内应该保留什么以及重叠层可以使用什么

再加上我的两便士

我们有使用mongo作为后端的微服务。我们使用netcore使用mediatr()在MSs中实现CQRS模式。我们有.Query和.Command功能

现在在我们的世界里,我们从来没有参加过活动采购。因此,在mongo级别,我们的读写模型(实体)是相同的。因此,对我们来说,最有效的方法是拥有一个实体模型,该模型可以通过每个命令/查询处理程序转换为不同的模型(如果需要)

如果您通过事件源(如此不同的读写模型)或其他方式进行CQR,请忽略我!但这对我们来说效果最好