域对象、工厂和存储库之间的依赖关系

Dependencies between domain object, factory and repository

好的,我阅读了很多关于存储库模式的内容,包括 Fowler 的书。 我非常清楚它是什么以及它做了什么,但是我不太确定它是如何被工厂 and/or 域对象调用的。

我的理解是存储库应该像域对象的内存集合一样工作,而工厂是 class 负责实例创建的:new myDomainObject()

考虑到这一点,显然存储库需要引用工厂才能从数据源查询中创建新对象。 (存储库 -> 工厂)

域对象也需要引用工厂才能创建新对象。

我的困境是当域对象想要检索现有对象时,它应该调用存储库还是工厂? 如果它直接调用存储库(Domain -> Repository -> Factory),那么它需要同时拥有对工厂和存储库的引用,这对我来说似乎太多了,但有那么糟糕吗?

另一方面,如果它像 factory.CreateObjectWithId(id) 那样调用工厂,那么工厂只需要将调用重定向到存储库 repository.GetById(id),而这最后一个将调用另一个方法对象创建的同一工厂(如果它不在内存中)factory.CreateObject(dataset),因此导致循环引用: Domain object -> Factory <--> Repository,这对我来说又不是什么好事。

那么您认为这些选项中哪个更好?或者还有其他选择吗?

您已经掌握了基础知识。 您的误解似乎来自于您假设领域对象应该是存储库的主要客户。事实并非如此,如果没有,您应该只从领域对象访问存储库另一种方式。一般尽量避免。

所以你的等式中缺少的部分是充当存储库的主要客户端的东西。

输入:应用程序服务

应用程序服务是包含用例逻辑(与域逻辑相反)的服务。它执行输入验证,实现访问管理,并负责事务控制。

这意味着应用服务将使用存储库从数据库加载聚合,对其进行处理,然后确保持久化更改(即提交事务)。

根据您使用的存储库的样式,将聚合保存回数据库会略有不同:

  • 对于集合式存储库,应用服务通常使用工作单元来跟踪和提交更改。
  • 使用命令式存储库,应用服务在对其执行业务操作后将聚合传递回存储库。

工厂和存储库

关于你关于工厂和存储库之间关系的问题,我想 也提供了你问题的答案。它的基本要点是:

  • 使用存储库中的工厂来避免重复聚合的实例化逻辑。
  • 确保概念从外部是清晰的,即不要将存储库看到的工厂的 "reconsitution interface" 暴露给其他 类。最好遵循 Interface Segregation Principle.

使用域中的存储库

如果您经常需要从数据库查询其他聚合以在域层执行业务任务,这表明您的聚合边界可能是错误的。

当然也有聚合边界没问题的情况,需要的对象不能作为参数传给领域对象。在这种情况下,使用域中的存储库是有意义的。在执行此操作之前,请务必尝试其他方法。在任何情况下,只依赖于存储库接口,从不依赖于具体的存储库实现。