Architecture 命令和查询中的逻辑重复

Architecture 命令和查询中的逻辑重复,architecture,domain-driven-design,cqrs,Architecture,Domain Driven Design,Cqrs,我们的体系结构在命令和查询方面是分开的,但并不完全是CQR,但我们尝试将这些东西分开。两者都使用相同的数据库。假设我们的要求是: 用户只能将消息发送到: 启用了消息传递系统的好友 它的亲密朋友都是高级用户 联系人列表中的任何管理员 当用户试图向某人发送消息时,我们检查这些要求,这样域规则就安全了。然而,现在我们需要向用户显示可能的消息收件人列表,并且所有这些规则都需要在查询端重复。这让我们很困扰 这违反了DRY还是ok?如果要引入新规则,必须在两个地方添加新规则。有什么好方法可以处理这种情况吗?

我们的体系结构在命令和查询方面是分开的,但并不完全是CQR,但我们尝试将这些东西分开。两者都使用相同的数据库。假设我们的要求是: 用户只能将消息发送到:

  • 启用了消息传递系统的好友
  • 它的亲密朋友都是高级用户
  • 联系人列表中的任何管理员
  • 当用户试图向某人发送消息时,我们检查这些要求,这样域规则就安全了。然而,现在我们需要向用户显示可能的消息收件人列表,并且所有这些规则都需要在查询端重复。这让我们很困扰


    这违反了DRY还是ok?如果要引入新规则,必须在两个地方添加新规则。有什么好方法可以处理这种情况吗?

    有多种方法可以共享代码。如果您在一个数据库中,那么一个简单的视图可能会起作用。限制潜在收件人的查询不能具有权威性;只有命令才能进行最终验证。查询只会帮助用户。该命令将在某个已知事务边界下执行,以确保遵循规则

    “当用户试图向用户发送消息时,我们会检查这些要求 所以域规则是安全的。但是现在我们需要显示列表 向用户发送的可能邮件收件人的列表,并且需要修改所有这些规则 在查询端被重复。这让我们感到困扰。”


    如果您对域模型和读取模型使用相同的数据库,将如何重复这种情况?即使您使用一个数据库来处理所有事情,在您的域和读取模型处理程序上,您也应该使用只读存储库来抽象它。另外,关于您提到的DRY,您在CQRS体系结构中会有很多,因为目标之一是能够更快地检索,而无需进行大量查询,因此您将以跨不同模型重复数据作为结束。

    问题是您使用的是一个数据库,因此您的CQR不完全相同。您可以尝试使用“写数据库”上的视图创建“读数据库”,以便“读”部分仅用于这些视图上的查询。@ema您的意思是“数据库中的视图”吗?然后我将在这个视图中重复这些规则。我考虑过创建非规范化的表,但我不确定应该如何实现数据复制。我应该使用域事件还是数据库触发器?尽管如此,仍有两个地方需要维护这些规则。如果数据库中的视图是一个选项,那么“逻辑”将隐藏在构建视图的查询中。如果您可以为只读数据创建一组不同的表,那么您可以使用域事件来对该表中的数据进行非规范化,这样,读取问题将仅限于“SELECT*FROM table”我的人完全正确。IMO:请确保如果违反规则,该命令会引发异常。您不能保证命令不会引发异常,因为即使查询100%正确,您也不知道用户屏幕上的数据有多陈旧。@JoshKodroff是的,我们不能100%确定,因此如果违反规则,我们的命令会引发异常。但例如,如果有几千个用户,并且消息可能只发送给其中的几个用户,那么查询应该返回尽可能最小的用户集。为了做到这一点,需要一些关于命令规则的知识。如果查询/视图试图重复此逻辑,则在添加新规则时可能会出现问题。@Machet您必须接受该重复,或者将该逻辑放在读写双方都可以看到的共享位置。但是请记住:查询并不是什么可以做什么和什么不能做的权威答案——命令处理程序才是。