我一直在阅读人们所说的关于 DDD 上下文中存储库位置(在哪一层)的内容,并发现我觉得不对劲的事情。例子:
确实,“就更“经典”的 DDD 而言,是的,域对象通常不允许在域之外的任何地方。
从这里
任何机构都可以指出我的其他参考资料,说明类似的情况吗?或者至少解释为什么?
对我来说正确的是一些存储库属于域层。正如埃文斯所说,存储库必须主要用于返回聚合以避免:
...违反域对象和聚合的封装...
并遵循:
...存储库减轻了客户的巨大负担,它现在可以与一个简单的、意图揭示的界面对话,并根据模型询问它需要什么...
因此,如果聚合是域对象并且由一些存储库返回,导致我们拥有必须知道如何重建这些域对象的存储库,则此类存储库实现将与域层的其他部分有非常密切的关系,例如简单的聚合类定义或重建工厂。
这些想法让我想到了第二个问题,App Layer 是否习惯性地从Naked Object上下文之外的存储库中检索域对象?我觉得是的,并且当性能或其他特定原因证明它是合理的时才需要使用数据传输对象,但是如果我们以避免知识泄漏的方式设计域层接口(只需公开所需的域对象和域服务到应用层而不是内部层),我们将是安全的。有没有感觉到这种思路?
我在前面的段落中说过一些,因为我认为某些存储库可能与域层没有那么紧密的联系,我谈论的是存储库以访问某种值或可枚举的对象,或者一般来说,与域没有关联的对象。Evans 也谈到,他认为有些时候全局搜索是有感觉的,这种全局搜索不会对设计造成任何伤害。
存储库存在的另一个原因是避免:
暴露技术基础设施和数据库访问...
和
将应用程序和域设计与持久性技术、多个数据库策略甚至多个数据源解耦。
存储库模式的其他目标让我一开始认为存储库不能在域层上,这与我已经说过的相矛盾。
最后,我认为如果我们根据其层位置对它们进行分类,则存在两种类型的存储库:
1-属于基础设施层的一个接口返回非领域层对象,避免最低层依赖于最高层。应用层将主要使用这种存储库来检索某种 VALUES/ENUMERABLE 对象。
2- 其他类型的存储库返回域对象并驻留在域层中。这种类型的存储库依赖于基础设施层提供的接口,用于基本上将应用程序和域设计与持久性技术分离,同时允许应用程序层在意图揭示接口中与域对话,并根据模型询问它需要什么。基础设施提供的这类接口可以用简单的原始数据合约来表达,并且看起来像是第二种形式的存储库,领域层通过该存储库向基础设施层询问形成领域对象和回复所需的数据来自应用层的请求。在我看来,实际上我可以以重复的代码结束在域对象非常简单且形式类似于它们在数据库中的存储方式的情况下。对于这些问题以及如何组织代码以在 DDD 的上下文中解决这些问题,我将不胜感激。
我将感谢这些想法的批评者,主要是那些突出其软点的人;)
这是我正在谈论的图表
编辑:
我对此了解得越多,我就越认为这种区别非常重要,并且可以让社区有所了解。例如,这里描述的是基础设施存储库(我写的类型 1),而这里描述的是域存储库(我写的类型 2)。
更重要的是,我认为像这样的战斗的一部分是因为我没有在这里做出的区分而被提升的。