【问题标题】:Repetition of logic in commands and queries命令和查询中的重复逻辑
【发布时间】:2014-04-03 23:49:59
【问题描述】:

我们的架构分为命令和查询,它不完全是 CQRS,但我们尝试将这些东西分开。两者都使用相同的数据库。假设我们有这样的要求: 用户只能将消息发送到:

  1. 已启用消息系统的密友
  2. 它的好朋友是高级用户
  3. 致联系人列表中的任何管理员

当用户尝试向某人发送消息时,我们会检查这些要求,因此域规则是安全的。但是,现在我们需要向用户显示可能的消息收件人列表,并且所有这些规则都需要在查询端重复。这让我们很困扰。

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

【问题讨论】:

  • 问题是您使用的是一个数据库,因此您不是完全 CQRS。您可以尝试使用 Write-DB 上的 Views 创建一个 Read-DB,以便读取部分仅是对这些视图的查询。
  • @ema 你的意思是在数据库中查看吗?然后我将在这个视图中重复这些规则。我考虑过创建非规范化表,但我不确定应该如何实现数据复制。我应该使用域事件还是数据库触发器?仍然有两个地方需要维护这些规则
  • 数据库中的视图是一个选项,那么“逻辑”将隐藏在构建视图的查询中。如果您可以为只读数据创建一组不同的表,您可以使用域事件来非规范化该表中的数据,这样读取问题就只有“SELECT * FROM Table”

标签: architecture domain-driven-design cqrs


【解决方案1】:

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

【讨论】:

  • 我的人完全正确 IMO:确保如果违反规则,该命令会引发异常。您不能保证该命令不会引发异常,因为即使查询 100% 正确,您也不知道用户屏幕上的数据有多陈旧。
  • @JoshKodroff 没错,我们不能 100% 确定,所以如果违反规则,我们的命令会抛出异常。但是例如,如果有几千个用户并且消息可能只发送给他们中的少数人,那么查询应该尽可能返回最小的用户集。为了做到这一点,需要一些关于命令规则的知识。如果查询/视图尝试重复此逻辑,则添加新规则时可能会出现问题。
  • @Macchet 您要么必须忍受这种重复,要么将这种逻辑放在读写端都可以看到的共享位置。但请记住:查询不是可以做什么和不可以做什么的权威答案——命令处理程序才是。
【解决方案2】:

“当用户尝试发送消息时,我们会检查这些要求 人,因此域规则是安全的。但是现在我们需要显示列表 可能的消息接收者给用户,所有这些规则都需要 在查询端重复。这让我们很困扰。”

如果您对域模型和读取模型使用相同的数据库,那将如何重复?即使您对所有事情都使用一个数据库,在您的域和读取模型处理程序上,您应该使用只读存储库对其进行抽象。此外,关于您提到的 DRY,您将在 CQRS 架构中拥有很多东西,因为其中一个目标是能够更快地检索到,而无需进行大量查询,因此您将以在不​​同的地方重复的数据结束模型。

【讨论】:

    猜你喜欢
    • 2017-09-01
    • 1970-01-01
    • 2015-03-16
    • 1970-01-01
    • 2021-01-23
    • 1970-01-01
    • 2013-03-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多