域对象,工厂和存储库之间的依赖关系 [英] Dependencies between domain object, factory and repository

查看:114
本文介绍了域对象,工厂和存储库之间的依赖关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,我读了很多有关存储库模式的内容,包括福勒的书。
我知道它的用途和作用,但是我还不确定工厂和/或域对象如何调用它。



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



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



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



我的难题是,当域对象要检索现有对象时,应调用存储库还是工厂?
如果直接调用存储库(Domain-> Repository-> Factory),那么它将需要同时具有对工厂和存储库的引用,这对我来说似乎太多了,但那样不好吗? / p>

另一方面,如果它像 factory.CreateObjectWithId(id)这样调用工厂,则工厂将拥有只将调用重定向到存储库 repository.GetById(id),最后这将调用同一工厂上的另一个方法来创建对象(如果它尚未在内存中) ) factory.CreateObject(dataset),因此导致循环引用:
域对象-> Factory<->存储库,这似乎也不是对我来说真的是一件好事。



那么您认为这些选择中哪个更好?还是还有其他选择?

解决方案

您已经掌握了基本知识。 您的误解似乎源于您认为域对象应该是存储库的主要客户端。并非如此,您应该仅从域对象访问存储库,除非没有其他方法。



因此,等式中缺少的部分是充当存储库主要客户的东西。



输入:应用程序服务



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



这意味着应用程序服务将使用存储库从DB,使用它进行一些操作,然后确保所做的更改得以保留(即,提交事务)。



根据您使用的存储库的样式,保存返回数据库的汇总略有不同:




  • 对于集合式存储库,应用程序服务通常使用个工作单元跟踪并提交更改。

  • 通过命令式存储库,应用程序服务在对其执行业务操作后将聚合传递回存储库。



工厂和仓库



关于您对工厂和仓库之间关系的疑问,我认为我的答案 pr以及回答您问题的答案。它的基本要点是:




  • 使用存储库中的工厂来避免重复聚合的实例化逻辑。

  • 请确保从外部了解概念,即不要将存储库看到的工厂的重构接口暴露给其​​他类。这可以通过遵循接口隔离原则来实现。



使用域中的存储库



如果您经常需要从数据库中查询其他聚合来执行业务



当然,在某些情况下,聚合边界很好,而所需的对象不能是传递给域对象作为参数。在这种情况下,可以使用域中的存储库。在执行此操作之前,请确保尝试其他方法。无论如何,仅依赖于存储库接口,而不依赖于具体的存储库实现。


Ok i read many things about the repository pattern, including Fowler's book. I know pretty good what it is and what it does, however what i'm not quite sure yet is how it is called by factories and/or domain objects.

What I understood is that the repository is supposed to act like an in-memory collection of domain object, and the factory is the class in charge of the instance creation: new myDomainObject()

With that in mind, it seems obvious that the repository will need a reference to the factory to create new objects from the data source queries. (Repository -> Factory)

Domain objects also need a reference to the factory in order to create new objects.

My dilemma is when a domain object want to retreive an existing object, should it call the repository or the factory ? If it calls the repository directly (Domain -> Repository -> Factory), than it would need to have both the references to the factory and the repository, which seems too much to me, but is it that bad ?

On the other hand, if it calls the factory like factory.CreateObjectWithId(id), then the factory would have to only redirect the call to the repository repository.GetById(id), and this last would call another method on the same factory for object creation (if it is not already in memory) factory.CreateObject(dataset), so that leads to a circular reference: Domain object -> Factory <--> Repository, which again does not seems really a good thing to me.

So in your opinion which of these options is better ? or is there another option ?

解决方案

You've got the basics right. The misunderstanding you have seems to come from your assumption that domain objects should be the primary clients of repositories. This is not the case, you should only access the repositories from domain objects if there is no other way. Try to avoid it in general.

So the missing piece in your equation is the thing that acts as primary client of the repositories.

Enter: The Application Service

An application service is a service that contains use case logic (as opposed to domain logic). It performs input validation, implements access management, and is responsible for transaction control.

This means the app service would use a repository to load an aggregate from the DB, do something with it, and then make sure the changes are persisted (i.e. commit the transaction).

Depending on the style of repository that you're using, saving an aggregate back to the DB is slightly different:

  • With collection-style repositories, the app service normally uses a unit of work to track and commit the changes.
  • With command-style repositories, the app service passes the aggregate back to the repository after performing the business operation on it.

Factories and Repositories

Regarding your questions about the relationship between factories and repositories, I think this answer of mine provides the answer to your question as well. The basic gist of it is:

  • Use the factory from the repository to avoid duplicating the instantiation logic of an aggregate.
  • Make sure the concepts are clear from the outside, i.e. don't expose the "reconsitution interface" of a factory that the repository sees to other classes. This is best achieved by following the Interface Segregation Principle.

Using Repositories from the Domain

If you constantly need to query other aggregates from the DB to perform business tasks in the domain layer, this is an indication that your aggregate boundaries could be wrong.

Of course, there are cases where the aggregate boundaries are fine, and the required objects cannot be passed to the domain object as parameter. In that case, it can make sense to use a repository from the domain. Be sure to try other approaches before doing this. In any case, only depend on a repository interface, never on a concrete repository implementation.

这篇关于域对象,工厂和存储库之间的依赖关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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