工作单位的实际用法储存库模式 [英] Practical usage of the Unit Of Work & Repository patterns

查看:89
本文介绍了工作单位的实际用法储存库模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个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();

如本例所示,应该独立使用工作单元和存储库,或者:

  • 工作单元应在内部使用存储库并具有加载对象的能力吗?
  • ...还是存储库应在内部使用工作单元并自动附加任何已加载的实体?

欢迎所有评论!

解决方案

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

另一方面,存储库模式是一种创建类似于聚合根上的集合的抽象的方法.您在存储库中看到的大多数情况通常与查询或查找聚合根"的实例有关.一个更有趣的问题(没有一个答案)是,添加处理查询聚合以外的方法的方法是否有意义.一方面,在某些有效情况下,您具有适用于多个聚合的操作.另一方面,如果您要对多个聚合执行操作,则实际上是对另一个聚合执行单个操作.如果您仅查询数据,则不知道您是否真的需要创建UoW隐含的边界.一切都取决于领域及其建模方式.

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

如果您想为组织外部的普通公众创建某种东西,那么我建议您以某种方式创建存储库接口/基础实现,以使它们可以直接与您的ORM交互,也可以不根据需要进行交互您的ORM用户的身份.如果这是内部的,并且您正在执行Aggregates.Entities中的持久性工作,则对您的存储库来说,可以利用您的UoW.对于通用存储库,可以从存储库实现中提供对UoW对象的访问,这可以确保对其进行初始化和适当处理.需要注意的是,有时您可能想在单个UoW边界内利用多个存储库,因此在这种情况下,您希望能够将已经准备好的UoW传递到存储库中.

I'm building an ORM, and try to find out what are the exact responsibilities of each pattern. Let's say I want to transfer money between two accounts, using the Unit Of Work to manage the updates in a single database transaction. Is the following approach correct?

  1. Get them from the Repository
  2. Attach them to my Unit Of Work
  3. Do the business transaction & commit?

Example:

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

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

unitOfWork.begin();
from.withdraw(amount);
to.deposit(amount);
unitOfWork.commit();

Should, as in this example, the Unit Of Work and the Repository be used independently, or:

  • Should the Unit Of Work use internally a Repository and have the ability to load objects?
  • ... or should the Repository use internally a Unit Of Work and automatically attach any loaded entity?

All comments are welcome!

解决方案

The short answer would be that the Repository would be using the UoW in some way, but I think the relationship between these patterns is less concrete than it would initially seem. The goal of the Unit Of Work is to create a way to essentially lump a group of database related functions together so they can be executed as an atomic unit. There is often a relationship between the boundaries created when using UoW and the boundaries created by transactions, but this relationship is more coincidence.

The Repository pattern, on the other hand, is a way to create an abstraction resembling a collection over an Aggregate Root. More often than not the sorts of things you see in a repository are related to querying or finding instances of the Aggregate Root. A more interesting question (and one which doesn't have a single answer) is whether it makes sense to add methods that deal with something other than querying for Aggregates. On the one hand there could be some valid cases where you have operations that would apply to multiple Aggregates. On the other it could be argued that if you're performing operations on more than one Aggregate you are actually performing a single action on another Aggregate. If you are only querying data I don't know if you really need to create the boundaries implied by the UoW. It all comes down to the domain and how it is modeled.

The two patterns are dealing at very different levels of abstraction, and the involvement of the Unit Of Work is going to be dependent on how the Aggregates are modeled as well. The Aggregates may want to delegate work related to persistence to the Entities its managing, or there could be another layer of abstraction between the Aggregates and the actual ORM. If your Aggregates/Entities are dealing with persistence themselves, then it may be appropriate for the Repositories to also manage that persistence. If not, then it doesn't make sense to include UoW in your Repository.

If you're wanting to create something for general public consumption outside of your organization, then I would suggest creating your Repository interfaces/base implementations in a way that would allow them to interact directly with your ORM or not depending on the needs of the user of your ORM. If this is internal, and you are doing the persistence work in your Aggregates.Entities, then it makes sense for your Repository to make use of your UoW. For a generic Repository it would make sense to provide access to the UoW object from within Repository implementations that can make sure it is initialized and disposed of appropriately. On that note, there will also be times when you would likely want to utilize multiple Repositories within what would be a single UoW boundary, so you would want to be able to pass in an already primed UoW to the Repository in that case.

这篇关于工作单位的实际用法储存库模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆