领域驱动设计(DDD)中的仓库应该返回什么?

3

我研究了领域驱动设计中的仓储,并发现有太多不同的东西。每个人对仓储都有不同的说法,这让我感到困惑。

我想知道:

  1. 仓储应包含哪些方法?
  2. 仓储一定要(或者更接近)返回什么?

谢谢。

3个回答

2
对于每个聚合根(AR),您应该有一个存储库。至少,存储库可能会有一个void Save(Aggregate aggregate)和一个Aggregate Get(Guid id)方法。返回的聚合始终是完全构成的。
我有时会添加用于特定用例的方法,以便仅更新某些数据位。例如,类似于void Activate(Guid id)之类的内容。这仅仅是为了避免操作比必要更多的数据。
在存储库上进行查询通常很麻烦,因为通常应避免查询您的域。对于这种情况,我的建议是使用一个更接近数据且以更原始格式呈现的“查询机制”,而不是领域对象或对象图。查询机制很可能会返回基元,例如int Count(Query.Specification specification),或者返回一系列“读模型”实例。

2
你说得对,存储库在不同的上下文中有不同的含义 - 许多作者都有自己的解释。我从多个角度理解它们:
  • 它们抽象了底层存储类型
  • 它们可以引入更接近领域模型的接口
  • 它们代表一组对象,因此作为聚合内存存储(相关对象的集合)
  • 它们代表相关对象的事务边界。
  • 它们不能包含重复项 - 就像集合一样。
  • 存储库可以仅包含一个对象,而无需内部复杂关系
因此,回答你的问题,存储库应该包含与集合相关的方法,如添加、删除、添加所有、按条件查找 - 而不是保存、更新、删除。它们可以返回整个聚合或聚合的部分或某些内部聚合关系 - 这取决于你的领域模型和你想要表示对象的方式。

1
Eric Evans在2003年创造了“领域驱动设计”的概念;因此,在这个背景下,任何定义的正确起点都是他的书。他在第6章(“领域对象的生命周期”)中定义了仓储模式。

仓储模式将一个类型的所有对象表示为一个概念集合(通常是模拟的)。它的行为类似于一个集合,但具有更复杂的查询能力。适当类型的对象会被添加和删除,而仓储背后的机制会将它们插入或从数据库中删除。

...

对于每种需要全局访问的对象类型,请创建一个对象,该对象可以提供该类型的所有对象的内存集合的假象。

仓储的主要用例:根据关键字返回正确的根实体。仓储实现作为一个模块,隐藏了您选择的持久性策略(参见:Parnas 1971)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接