【问题标题】:DDD: Should we bypass domain models sometimes?DDD:有时我们应该绕过领域模型吗?
【发布时间】:2023-04-02 20:00:07
【问题描述】:
我从事一个项目,我们试图尽我们所知应用 DDD。我们还使用 CQRS 和洋葱架构。
我们有聚合,我们有存储库。对于每个帖子,我们使用工厂服务,然后使用聚合存储库保存结果,当然,我们在不使用任何工厂的情况下调用存储库。
到目前为止一切顺利!
现在,这对我来说有点可疑,但我很想听听其他意见:对于某些获取,而不是使用域模型,由于性能问题,我们不想加载整个聚合只是为了例如,获取 5 个字段,因此我们绕过域模型,我们使用单独的存储库仅用于该 CQRS 查询。这个存储库(我们称之为搜索引擎)返回一个 DTO(不是正常存储库返回的域模型)。我们绕过整个域,一切都发生在应用层。
这正常吗?这个臭吗?这看起来像我们的领域模型设计不正确吗?这是不好的做法吗?这是否符合 DDD 和干净的架构?
我很想听听你的想法
【问题讨论】:
标签:
domain-driven-design
cqrs
ddd-repositories
clean-architecture
【解决方案1】:
在现代设计中,在响应安全请求时绕过域模型是正常的。
从历史上看,当 Evans 描述实现模式时,“数据库”只是隐藏在存储库抽象背后的一些实现细节。因此,对数据的访问受到存储库接口提供的限制;这意味着聚合根,或聚合根的集合。
您可以在Cargo Booking sample 中看到这一点,其中存储库提供聚合根列表,然后该根列表转换为 DTO 列表。
我将此归因于 Evans 大约在 2003 年从事 Java 开发的事实;有一堆隐含的约束,没有比当时“我们认为好的 OO 设计看起来像这样”更真实的理由。
公平地说,您希望将读取模型基于写入模型将使用的数据,这并非完全不合理。写入模型预计会随着业务的需要而改变;如果我们希望视图代表模型,那么视图将需要进行相同的更改,并且如果一个直接依赖于另一个,则更容易确保。
随着分布式域驱动设计(最终成为命令查询职责分离)的引入,我们开始放弃“聚合”支持安全查询的概念。如果你想查询数据,你需要一个数据库——这就是数据库的作用。
领域模型的唯一职责是管理对存储在数据库中的信息的更改。