如何在 DDD 中实现仅子查询

How to implement a query only sub- in DDD

在过去的几个月里,我们一直在尝试重构和改进基于 DDD 和六边形架构的后端服务的架构和风格。不幸的是,我们对 DDD 及其最佳实践还很陌生。

我们的产品是关于车队管理和监控的。我们的一项功能是用户可以获得他们管理的车辆的报告。这些报告大多是对数据库的简单查询,在应用层具有一些聚合和域逻辑。这是我们出现的问题。对于大多数应用程序,我们使用 CQRS 并在我们的应用程序层中定义了 command/query 处理程序。我们注入到此处理程序的依赖项以及我们的数据库和缓存使用存储库等进行抽象

对于报告功能(我不知道称其为子域是否合适),我们不知道该做什么以及如何设计实体。其中一些报告很复杂,涉及对为 db 获取的多个数据集进行连接、验证等,其他一些是非常简单的查询,将它们全部压缩在查询处理程序中似乎不合适,我们不知道我们是否需要此处或聚合不是。所以我们不再陷入困境和困惑。

TL;DR:如果您不尝试应用 DDD 模式,您会怎么做?这样做。


报告通常是只读的。它们只是采用方便形式的信息副本。

这意味着您不需要“为了数据更改我们将其视为一个单元的关联对象集群”(聚合),因为我们不会更改数据。您不需要存储库和工厂,因为您不需要管理聚合生命周期。你不需要实体,因为你不需要信息变化的规则。

“值对象”有时很有用,但将信息复制到一个值中以便您可以再次读取它是浪费时间。

(例外情况可能类似于独立应用程序,其中您的报告是对当前存储在内存聚合中的信息的描述。)

要考虑的一件事是 OLTP (Online Transaction Processing) vs OLAP(联机分析处理)。这与 DDD 无关,与数据结构和他们试图解决的问题有很大关系。

简而言之,OLTP 是关于通过利用参照完整性等支持应用程序中的事务(例如插入和更新); OLAP 是关于报告和分析以及构建数据以更好地支持它。

这取决于您的报告需求的全面程度(功能要求、数据结构/DDD 模型的复杂性、查找次数、数据量、用户行为、数据波动性等)。如果您认为权衡取舍是合理的,那么您可能希望在支持应用程序主要功能的部分和与报告相关的部分之间逻辑地划分您的应用程序。

您可以通过以下几种方式执行此操作:

  • DDD代码&OLTP数据库;由报告代码和 OLAP 数据库补充。此选项是最严厉的选项之一,但也是最容易理解的选项 - 完全分离。
  • 整个应用程序的 DDD 代码,“报告”作为“纯”DDD 的辅助部分。支持您认为合适的数据库结构。
  • DDD 代码,所有“报告”都无缝且优雅地融入现有的纯 DDD 代码中。支持您认为合适的数据库结构。