DDD 中的聚合可以有多个存储库吗?

All*_*nph 2 persistence domain-driven-design datamapper repository ddd-repositories

我读过这个关于类似问题的问题,但它并没有完全解决我的问题。

我有一个应用程序,需要使用 API 中的数据。问题是这样做存在性能和技术限制。性能限制是显而易见的。技术限制在于 API 不支持我需要进行的一些更精细的查询。

我决定使用 MySQL 作为可查询缓存。

由于我需要从 API 检索的数据不会经常更改,因此我决定每天刷新一次缓存,因此我不需要任何复杂的映射器来检查缓存中是否有数据,如果没有则回退到 API。这是我的第一个设计,但我意识到,当 API 无法支持我需要进行的大多数查询时,这并不是很实用。

现在我为每个聚合都有一组两个映射器。一种用于 MySQL,一种用于 API。

我现在的问题是如何从域中隐藏持久性的复杂性,以及我似乎需要多个存储库的事实。

理想情况下,我会有一个两个映射器都遵守的界面,但正如之前所披露的那样,这是不可能的。

是否可以拥有多个存储库,每个映射器一个?

Voi*_*son 6

DDD 中的聚合可以有多个存储库吗?

简短的回答:是的。

更长的答案:您在埃文斯的原书中找不到任何关于多个存储库的建议。正如他所描述的那样,领域模型将具有聚合的一种表示而存储库抽象为消费者提供了聚合存储在内存集合中的错觉。

很大程度上,这是有道理的——您试图确保聚合边界内的数据写入是一致的,因此您需要一个单一的更改权限。

但是......没有什么特殊原因表明读取需要与写入经过相同的代码路径。的世界。这立即给您带来的想法是,用于读取的内存中表示形式可能需要与用于写入的内存中表示形式进行不同的优化。

在更一般的形式中,您会发现您正在建模的概念对于每个用例可能有不同的表示。

对于您的情况,有时适合从 RDBMS 读取,有时从 API 读取,有时两者都适合,这并不是完全匹配 - 存储库接口向消费者隐藏了实现细节,但您仍然需要费心与实施。

您可能会考虑的一件事是您的要求;每个用例中的数据需要有多新鲜?CQRS 模式中经常放宽的一个约束是写入的效果可以立即用于读取。要问的重要问题是,如果数据尚未缓存,您是否可以简单地报告“数据不可用”而不访问 API?

如果是这样,那么访问缓存数据的用例只需要一个存储库实现。