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