【问题标题】:CQRS & DDD - Domain Model Business Rules validation using cqrs read modelCQRS & DDD - 使用 cqrs 读取模型的域模型业务规则验证
【发布时间】:2012-05-18 12:04:43
【问题描述】:

我是 DDD 和 CQRS 模式的新手,我想听听您对如何验证域实体的看法。 我将使用常见示例 Order->OrderLine,其中 Order 是 AR。

聚合中业务规则的验证是通过 AR 来确保一致性。 如何验证需要订单聚合之外的数据的业务规则?

我也在使用 CQRS 方法,我认为使用 ReadModel 获取我需要验证我的业务规则的数据不是一个糟糕的选择......你怎么看?

【问题讨论】:

  • 验证通常意味着输入,所以它会发生在命令端(写端)。您将对读取模型进行哪些验证?

标签: domain-driven-design cqrs


【解决方案1】:

根据我的 CQRS 经验,我认为 ReadModel 是最终一致的,因此我不会 100% 相信 ReadModel 代表系统的当前状态。当您想要分发和复制您的 ReadModels 时,情况就更是如此。

我只想使用 ReadModel 来限制发送到您的应用程序的无效命令的数量。

听起来您想开始考虑域服务,它可用于封装位于单个聚合/实体/值对象边界之外的域逻辑。

正如大卫在这里指出的Implement Domain Services as Extension Methods for the repository,Jimmy Bogard 有一个定义http://lostechies.com/jimmybogard/2008/08/21/services-in-domain-driven-design/

【讨论】:

  • 确实域服务在这里看起来很合适;问题是:还需要哪些其他数据?我假设它是存储在另一个聚合中的数据?
  • 是的,存储在另一个聚合中的数据,例如与 AR 没有任何关联的数据。域服务似乎是一个不错的方法
  • 对域服务的需求非常强烈,表明缺少聚合根。
【解决方案2】:

是的,使用读取模型进行命令验证。我称之为“命令上下文”——世界的当前状态,基于哪个命令可能有效或无效。在 CQRS 中,世界的当前状态在您的读取模型中表示。用户正在根据它做出决定,应该发出什么命令。

您还可以考虑各种方式来指导用户决策,这样他就不会发出无效命令(如果用户名不是唯一的,则提前警告等)。

【讨论】:

  • 正如 mouters 指出的那样,读取模型最终是一致的。这意味着它是过去某个时间点的世界状态。域是唯一真正的“世界当前状态”。
  • 如果您尝试支持跨 AR 一致性,那么您就有点放弃了可扩展性 - 这意味着,首先使用 cqrs 的理由就少了。
  • 是的,如果实现是纯 CQRS 并使用两个不同的数据库,一个用于写入,另一个用于通过域事件更新的读取,读取模型不是查询一致/最新数据的好方法
  • @driushkin 所说的完全正确;您可以将读取模型用于命令验证 (即降低命令失败的可能性),但我认为这不是问题所在。问题似乎与域业务规则不变量有关。这里涉及的数据需要是“事实来源”。我认为混淆来自作者使用“验证”这个词。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-05-12
  • 2017-06-27
  • 1970-01-01
  • 1970-01-01
  • 2019-05-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多