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

发布于 2024-11-08 17:36:02 字数 706 浏览 10 评论 0原文

我正在构建一个 ORM,并尝试找出每个模式的确切职责。假设我想使用 工作单元用于管理单个数据库事务中的更新。

下面的方法正确吗?

  1. 从存储库获取它们
  2. 将它们附加到我的工作单元
  3. 进行业务交易和处理犯罪?

示例:

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

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

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

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

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

I'm building an ORM, and try to find out what the exact responsibilities of each pattern are. 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 = accountRepository.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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

水中月 2024-11-15 17:36:02

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

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

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

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

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.

Hello爱情风 2024-11-15 17:36:02

我建议您在存储库内部使用 UoW 时使用此方法。这种方法有一些优点,特别是对于 Web 应用程序。

在 Web 应用程序中,建议使用 UoW 的模式是每个 HTTP 请求的工作单元(会话)。因此,如果您的存储库将共享 UoW,您将能够对其他存储库(例如由多个聚合引用的数据字典)请求的对象使用第一级缓存(使用身份映射)。此外,您只需提交一个事务而不是多个事务,因此它在性能方面会更好。

你可以看看 Hibernate/NHibernate源代码,是Java/.NET世界中成熟的ORM。

I recommend you to use this approach when the repository uses UoW internally. This approach has some advantages, especially for a web application.

In a web application, the recommended pattern of using UoW is Unit of Work (session) per HTTP request. So if your repositories will share UoW, you will be able to use the first level cache (using identity map) for object that were requested by other repositories (like data dictionaries that are referenced by multiple aggregates). Also, you will have to commit only one transaction instead of multiple, so it will work much better in terms of the performance.

You could take a look at Hibernate/NHibernate source code that is mature ORMs in Java/.NET world.

¢蛋碎的人ぎ生 2024-11-15 17:36:02

这取决于您的工作界限。如果它们要跨越多个存储库,那么您可能必须创建另一个抽象以确保覆盖多个存储库。它就像在域驱动设计中定义的一个小型“服务”层(DDD)。

如果您的工作单元几乎是每个存储库,那么我会选择第二个选项。

然而,我的问题是,在编写 ORM 时如何担心存储库?它们将由您的工作单元的消费者定义和使用,对吧?如果是这样,您别无选择,只能提供一个工作单元,您的消费者将必须将存储库纳入您的工作单元,并且还将负责控制工作单元的边界。不是吗?

It depends on what your work boundaries are going to be. If they are going to span multiple repositories then you might have to create another abstraction to ensure that multiple repositories are covered. It would be like a small "service" layer that is defined in domain-driven design (DDD).

If your unit of work is going to be pretty much per Repository then I would go with the second option.

My question, however, to you would be, how can you worry about repository when writing an ORM? They are going to be defined and used by the consumers of your Unit of Work right? If so, you have no option but to just provide a Unit of Work and your consumers will have to enlist the repositories with your unit of work and will also be responsible for controlling the boundaries of unit of work. Isn't it?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文