CQRS和DDD - 使用CQRS读模型验证领域模型业务规则

3
我是DDD和CQRS模式的新手,想请教您一个问题:如何验证领域实体呢?让我们以常见的Order->OrderLine为例。在这个案例中,Order是AR(聚合根),因此,在AR中验证业务规则可以保持一致性。但是,如果需要使用Order聚合之外的数据来验证某些业务规则,该怎么办呢?我采用CQRS方法,认为使用ReadModel获取所需数据进行业务规则验证不失为一种好方法。您认为呢?

验证通常意味着输入,因此它会在命令端(写入端)发生。您将在读模型上执行哪些验证? - Davin Tryon
2个回答

3
根据我的CQRS经验,我认为ReadModel是最终一致的,因此我不会百分之百地相信ReadModel代表系统的当前状态。当您想要分发和复制ReadModels时,情况变得更加如此。
我只想使用ReadModel来限制发送到应用程序的无效命令数量。
听起来您想开始思考领域服务,它可以用于封装超出单个聚合/实体/值对象边界的领域逻辑。
正如David在这里指出的那样Implement Domain Services as Extension Methods for the repository,Jimmy Bogard有一个定义http://lostechies.com/jimmybogard/2008/08/21/services-in-domain-driven-design/

确实,领域服务在这里似乎是合适的;问题是:还需要什么其他数据?我猜想这可能是存储在另一个聚合中的数据? - David Masters
是的,数据存储在另一个聚合中,例如与AR没有任何关联。领域服务似乎是一个不错的方法。 - JPP
需要领域服务的需求很强烈,这表明缺乏聚合根。 - Arnis Lapsa

-1

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

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


1
正如Mouters所指出的那样,读模型是最终一致的。这意味着它是过去某个时间点世界的状态。领域是唯一真正的“当前世界状态”。 - Shane Courtrille
如果你试图支持跨AR的一致性,那么你有点放弃了可扩展性——这意味着,使用cqrs的第一个原因就少了一个。 - driushkin
如果实现是纯CQRS并使用两个不同的数据库,一个用于写入,另一个通过领域事件更新用于读取的话,那么读模型不是查询一致/最新数据的好方法。 - JPP
@driushkin所说的完全正确;您可以使用读取模型进行命令验证(即降低命令失败的可能性),但我认为这不是问题所在。问题似乎是关于领域业务规则不变量的。这里涉及的数据需要成为“真相来源”。我认为混淆来自作者对“验证”一词的使用。 - David Masters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接