我读过this question about something similar,但它并没有完全解决我的问题。
我有一个应用程序,我需要使用API中的数据。问题是这样做有性能和技术限制。性能限制很明显。技术限制在于API不支持我需要进行的一些更细粒度的查询。
我决定使用MySQL作为可查询缓存。
由于我需要从API检索的数据没有经常更改,我决定每天刷新一次缓存,所以我不需要任何复杂的映射器检查我们是否有缓存中的数据,如果没有回到API。这是我的第一个设计,但我意识到,当API无法支持我需要进行的大多数查询时,这不太实用。
现在我为每个聚合都有一组两个映射器。一个用于MySQL,一个用于API。
我现在的问题是如何隐藏域中持久性的复杂性,以及我需要多个存储库这一事实。
理想情况下,我会有一个接口,两个映射器都遵守,但如前所述,这是不可能的。
是否可以拥有多个存储库,每个映射器一个?
答案 0 :(得分:1)
DDD中的聚合可以有多个存储库吗?
简答:是的。
更长的答案:你在Evans的原书中找不到任何关于多个存储库的建议。正如他所描述的那样,域模型将具有 聚合的一种表示形式,并且存储库抽象为消费者提供了聚合存储在内存中集合中的错觉。
很大程度上,这是有道理的 - 您正在尝试确保对聚合边界内的数据的写入是一致的,因此您需要一个权限来进行更改。
但是......没有特别的原因,读取需要通过与写入相同的代码路径。欢迎来到cqrs的世界。立即给出的内容是,读取的内存表示可能需要与用于写入的内存表示不同地进行优化。
在更一般的形式中,您会认为您正在建模的概念可能对每个用例都有不同的表示。
对于您的情况,有时候从RDBMS读取,有时候从API读取,有时两者都是,这不是完全匹配 - 存储库接口隐藏了消费者的实现细节,但是你仍然需要为实施而烦恼。
您可能会关注的一件事是您的要求;每个用例中的数据需要有多新鲜?在CQRS模式中经常放宽的约束是写入的效果立即可用于读取的想法。要问的重要问题是,如果数据尚未被缓存,您是否可以简单地报告"数据不可用"没有达到API?
如果是这样,那么访问缓存数据的用例只需要一个存储库实现。
答案 1 :(得分:0)
如果您使用外部API来读取和修改数据,您可以在本地缓存它们以便更快地读取,但我会避免使用域存储库。
从域的角度来看,您似乎需要一个服务来查询(或只是CQRS实现中的查询)某些数据,您可以使用服务,内部可以调用某些远程API或从本地缓存读取(mysql,无论如何)。
当您读取本地缓存时,您可以开发一个存储库以将您的逻辑与数据库实现分离,但这与域存储库的概念不同,它只是您的技术实现的一个细节,它具有与您的域名无关
如果远程服务开始提供您需要的查询,您将更改如何执行查询的实现,调用远程API而不是db,但您的域模型不应更改。
域存储库用于加载和保留您的聚合,同时如果您正在使用外部聚合(在不同的上下文中,子域),您需要使用服务与它们进行交互。