使用存储库模式,最好是一起或单独保存父和子对象?

时间:2009-06-18 00:30:51

标签: design-patterns repository-pattern

让父对象Employee具有Address子对象列表:

class Employee
{
    List<Address> addresses;
}

和存储库方法:

void Insert(Employee);

此存储库中的代码是否应该尝试保存父Employee以及子Address对象,还是单独的存储库应该处理父对象和子对象?

如果是单独的存储库,那么当在客户端代码中保存Employee对象及其子节点时,这应该是在该级别的单独调用,在某种服务中组合还是有另一种选择?

5 个答案:

答案 0 :(得分:5)

存储库应该处理整个聚合对象(父对象和所有子对象),因为这就是使它成为存储库的原因。如果你要单独保存根对象和子对象,那么你正在使用的模式实际上并不称为存储库(尽管它可能仍然是一个非常好的解决方案)

“Repository”只是一个特定数据访问模式的便捷名称,它可以一次性加载和保存整个聚合 - 所以当你向另一个开发人员说你正在使用存储库模式时,他们知道这是正在发生的事情

答案 1 :(得分:1)

实体之间有两种链接。

一个 引用:当一个实体包含对另一个实体的引用时。这些实体是独立的,其中任何一个都可以与另一个适当的实体相结合。

例如:客户和产品,用户和地址等。

另一种类型是 aggreagting :当少数实体代表单个对象时,由于某些原因,这些对象存储在少数几个表中/分成几个类。但它仍然是一个 单个 对象:一个部分没有其他部分没有意义,也不能与其他实体结合。在这种情况下,一个实体始终是 major ,删除主要内容总是会导致删除聚合实体。

例如:订购和订购商品,房屋及其房间等。

引用表示关系,聚合表示拥有。

<强> SO 保存带引用的实体不应该保存引用的实体(引用实体的情况除外,但在这种情况下,最好先保存引用的实体)。

使用聚合保存实体必须保存聚合实体。在单笔交易中。因为这是一个单一的对象。另外,最好不要单独保存聚合(仅当性能非常关键时) - 否则会出现很多并发问题。

答案 2 :(得分:0)

我会尝试使用工作单元模式,您可以在其中打开,进行更改,提交,然后它就会找出正确的事情。

如果你在关系数据库中,你最终会得到像Hibernate这样的表,每个表都有一个映射器。如果您在非关系数据库中,则可能必须具有创造性,并将域对象标记为IAggregateRoot或其他内容,以了解哪些具有自己的存储库,哪些不具有。

例如,如果Employees存储在一个SOA中,而Addresses存储在另一个SOA中,则它们每个都是IAggregateRoots,理想情况下,工作单元会自动将每个脏实例关闭到其相应的存储库以进行保存。

那么它对客户端代码是透明的,但不是无用的间接层(比如服务主要是在java世界中,无论如何 - 并不总是,但是我见过的那些)。

我喜欢DDD,但我认为它过度炒作了存储库,并且凭经验导致了很多混乱,因为人们总是在问如何正确地做这些。

除非我的系统具有已知的多个基于SOA的后端(并且不仅仅是“嘿,我们有一天可能会成为亚马逊并且需要它”),否则我会亲自回避存储库。基于Hibernate的映射器/ DAO /东西,当然,但它们看起来比存储库更简单,更具体。

答案 3 :(得分:0)

我更喜欢每个表的存储库,但将它们粘合到一个聚合存储库中:

public RootEmployeeRepository (
  IEmployeeRepository employeeRepository, 
  IAddressRepository addressRepository)
{
  // init
}

public SaveEmployee (Employee employee)
{
  // call IEmployeeRepository to save the employee record minus childen
  // call IAddressRepository to save employee.addresses
  // commit all changes to the DB via UnitOfWork
}

答案 4 :(得分:0)

我更喜欢NHibernate为您处理级联保存。