【问题标题】:Repository pattern: repository per aggregate or per underlying data store?存储库模式:每个聚合或每个底层数据存储的存储库?
【发布时间】:2011-03-14 10:56:21
【问题描述】:

recommended 每个聚合有一个存储库。

但是,我有一个案例,可以从 2 个异构数据存储中获取相同的聚合对象。对于背景,该对象是:

  1. 从数据存储 A 获取(远程和只读)
  2. 呈现给用户进行验证
  3. 验证时,导入数据存储B(本地和读写)
  4. 可以从数据存储B中获取和修改

显然(或没有),我不能为此拥有一个唯一的聚合存储库 - 在某些时候我需要知道从哪个数据存储中获取对象。

鉴于域层应该忽略基础设施,我的特殊情况以某种方式打破了我对如何正确实施存储库模式和 DDD 的理解。

我是不是搞错了?

【问题讨论】:

    标签: language-agnostic architecture domain-driven-design repository-pattern ddd-repositories


    【解决方案1】:

    我是不是搞错了什么?

    在我看来,您的错误在于同一数据有两个数据存储。

    如果这种冗余确实有充分的理由,那么这两个聚合在某些方面肯定是不同的,这可能证明将它们视为单独的聚合并拥有两个存储库是合理的。

    如果您想将它们视为单个聚合,单个存储库应该知道如何消除歧义并处理正确的数据存储,但将数据存储的知识封装在您的域模型之外。

    编辑:

    在 cmets 中解释的情况下,其中一个数据存储是只读的,而另一个是本地可修改副本,实际上您必须拥有两个数据存储。您的存储库需要了解这两个数据存储,并且仅当它在本地找不到某些内容时才使用远程只读存储。从远程检索到某些内容后,它应立即将其保存到本地,然后使用本地副本。

    这个逻辑有点像缓存代理,但不完全是,因为远程是只读的,本地是读写的。它可能包含足够的逻辑以提取到存储库使用的服务中,但不应暴露给域。

    这种情况也有一些你需要考虑的风险。一旦你在本地保存了一些东西,你就有了相同数据的两个版本,它们会不同步。如果在您更改本地后,对远程具有写入权限的人更改了它,您会怎么做?

    【讨论】:

    • @Don: “在我看来,您的错误在于同一数据有两个数据存储” -> 数据存储 A 是我不使用的远程引用'没有写权限。在某些时候,出于性能原因和可能的修改,我需要在本地数据存储 B 中表示该数据。
    • @Maxim Gueivandov:为此,我将使用单个存储库,并隐藏存储库中哪个数据存储的决定,以免知识污染域。
    • @Don: “如果你想把它们当作一个单一的聚合体,一个单一的存储库应该知道如何消除歧义并处理正确的数据存储”:这怎么可能达到了吗?
    • @Maxim:查看我的更新。发表评论有点太长了。
    • @Don:感谢您的澄清。但是,要求 #2(在导入之前必须将对象呈现给用户进行验证)禁止我静默同步 2 个数据存储。我需要一种方法来区分表示层的 2 个数据源。我相信您建议拥有 2 个不同的存储库,因此 2 个不同(但结构相同)的聚合对象最适合此要求。你不同意吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-17
    • 1970-01-01
    • 2012-03-10
    • 1970-01-01
    相关资源
    最近更新 更多