CQRS与规范模式


这是一篇关于两个DDD模式如何相互矛盾的文章。
这两种领域驱动设计模式 - CQRS规范模式 - 是相互矛盾。 不仅仅轻微矛盾,他们在最根本的方面存在分歧。
让我们首先回顾一下他们的定义。 CQRS模式是将单个统一模型拆分为两个:一个用于读取,另一个用于写入。 这种看似简单的分离带来了非常显着的好处,其中最重要的是简单性。
应用程序的命令端和查询端具有截然不同的需求。 为这些方面引入单独的模型是明确区分这种差异的一种自然方式。 反过来,这可以让您从代码库中去除很多复杂性。 通过这种分离,您不必担心使用相同的代码处理两个完全不同的用例。 您可以独立地关注它们中的每一个,并提出在每种特定情况下最有意义的解决方案。 你可以将其视为在架构级别应用的单一责任原则。 最后,你得到两个模型,每个模型只做一件事,都做得很好。
规范Specification模式是将一段领域知识封装到一个单元中 - 称为规范 - 然后在不同的场景中重用。 有三种这样的场景:数据检索,内存中验证和新对象的创建。
使用规范创建新对象的场景非常罕见,在这里和我们讨论的矛盾主题不相关。 数据检索是从数据库中获取数据 - 查找与规范匹配的记录。 内存验证是指检查某个对象是否符合规范描述的标准。
这很有用,因为它允许你避免域知识重复。 当您向用户显示数据时,相同的规范类可用于验证传入数据和从数据库中过滤数据。同时,CQRS模式提出了显示与写入的两者必须分离。

CQRS与规范模式
验证属于命令写入端。 它在数据突变之前,通常在更改内容之前验证传入的数据。 而数据检索属于读取方查询端。 客户端查询系统中的数据。
所以这里有一个明显的矛盾。 一方面,规范模式主张针对这两个问题建立单一域模型。另一方面 - CQRS主张将域模型分成两部分并分别处理这些问题。
你在这里看到的是DRY原则之间矛盾的经典例子,它表示不重复自己,松散耦合的原则。 这两个原则都是基础原则,它们是您在日常工作中使用的大多数软件开发实践的核心。
那么,你更喜欢哪一个?

这里的指导原则是: 松散耦合在绝大多数情况下都胜出 。
在高耦合和领域知识重复之间进行选择时,后者是较小的邪恶。 当你复制领域知识时,它不是很方便,但是当你将它与替代方法进行比较时并没有那么糟糕。
替代方案 - 高耦合 - 可能是毁灭性的。 有了它,你几乎被双手绑在背后。 您的选项受到严格限制,因为您不仅要考虑您开发的组件所提出的要求,还要考虑依赖于此实现的所有其他组件。
在具有输入验证和数据检索的场景中,这表现为无法有效地从数据库查询数据。 您不能使用底层数据存储的本机查询机制,必须回退到最低的公分母。 也就是说,提出一种解决方案,既不能很好地处理这两种情况。
遗憾的是,规范模式仅适用于您不需要复杂查询逻辑的简单情况。 在这种情况下,使用这种模式可能没问题。
但是,对于大型系统,您几乎总是应该选择松散耦合来防止读写之间的域知识重复。 为手头的问题选择最合适的解决方案的自由胜过DRY原则。

总结
那么,在这里,您可以了解CQRS和规范模式之间的巨大矛盾。

  • CQRS是关于将读取和写入分成单独的模型。
  • 规范模式是关于在读写中重用域逻辑的位。
  • CQRS代表松散耦合的首要原则。
  • 规范模式代表DRY的总体原则(不要重复自己,避免领域知识重复)。
  • 除了最简单的情况外,在绝大多数情况下,松耦合胜过DRY。