工作单元和存储库模式的实际用法

Ben*_*min 17 orm domain-driven-design unit-of-work repository-pattern domain-model

我正在构建一个ORM,并试图找出每个模式的确切职责.假设我想在两个帐户之间转移资金,使用工作单元来管理单个数据库事务中的更新.以下方法是否正确?

  1. 从存储库中获取它们
  2. 将它们附加到我的工作单元
  3. 做生意交易和提交?

例:

from = acccountRepository.find(fromAccountId);
to = accountRepository.find(toAccountId);

unitOfWork.attach(from);
unitOfWork.attach(to);    

unitOfWork.begin();
from.withdraw(amount);
to.deposit(amount);
unitOfWork.commit();
Run Code Online (Sandbox Code Playgroud)

应该像在这个例子中那样独立使用工作单元和存储库,或者:

  • 工作单元是否应该在内部使用存储库并且能够加载对象?
  • ...或者存储库是否应在内部使用工作单元并自动附加任何已加载的实体?

欢迎所有评论!

ckr*_*mer 16

简短的回答是存储库将以某种方式使用UoW,但我认为这些模式之间的关系不像最初看起来那么具体.工作单元的目标是创建一种方法,将一组数据库相关的函数基本上集中在一起,以便它们可以作为原子单元执行.使用UoW时创建的边界与事务创建的边界之间通常存在关系,但这种关系更为巧合.

另一方面,Repository模式是一种在Aggregate Root上创建类似于集合的抽象的方法.通常,您在存储库中看到的各种事物与查询或查找聚合根的实例有关.一个更有趣的问题(并且没有单一答案的问题)是添加处理除了查询聚合之外的其他方法的方法是否有意义.一方面,可能存在一些有效的情况,其中您有适用于多个聚合的操作.另一方面可以说,如果您在多个Aggregate上执行操作,那么您实际上是在另一个Aggregate上执行单个操作.如果您只是查询数据,我不知道您是否真的需要创建UoW隐含的边界.这一切都归结为领域以及如何建模.

这两种模式处理的是非常不同的抽象层次,工作单元的参与将取决于聚合体的建模方式.聚合可能希望将与持久性相关的工作委托给其管理的实体,或者聚合与实际ORM之间可能存在另一层抽象.如果您的聚合/实体本身正在处理持久性,那么存储库也可能适合管理该持久性.如果没有,那么在您的存储库中包含UoW是没有意义的.

如果您想在组织外部为公众消费创建一些内容,那么我建议您创建Repository接口/基本实现,以便它们可以直接与您的ORM交互,具体取决于用户的需求你的ORM.如果这是内部的,并且您在Aggregates.Entities中执行持久性工作,那么您的存储库可以使用您的UoW.对于通用存储库,从存储库实现中提供对UoW对象的访问是有意义的,这可以确保对其进行初始化和适当处理.在这方面,有时您可能希望在单个UoW边界内使用多个存储库,因此在这种情况下,您希望能够将已经准备好的UoW传递到存储库.