DDD:聚合根问题

Arn*_*psa 16 domain-driven-design aggregateroot

假设我有2个实体--Foo和Bar.Foo是一个聚合根,包含Bar.据我所知,它应该是这样的:

public class Foo{
    private readonly Bar Bar;
}
Run Code Online (Sandbox Code Playgroud)

我想为用户提供从定义列表中选择Bars for Foos的功能(并进行更改).

如果存储库应该仅用于聚合根,则意味着Bar实体将没有存储库.

这会导致问题 - 如果没有引用Foo,就无法独立创建/更新Bar.

这是否意味着Bar应该拥有一个存储库,尽管没有Foo它没有意义?

que*_*en3 18

如果要从不与Foo关联的Bars列表中进行选择,则这不是聚合根.例如,如果没有订单,则无法获取OrderItems列表,因此这是单个聚合根(订单),但您可以获取要分配给OrderItems的产品列表,因此Product不是Order聚合根的一部分.

请注意,虽然OrderItem是Order聚合根的一部分,但您仍然可以单独创建和更新它.但是,如果不参考Order,你就无法得到它.对于你的Bar来说,即使它是Foo的一部分,你也可以得到每个(Foo.Bars)并使用它,或者做Foo.AddBar(new Bar()).但是如果你需要在没有Foo的情况下获得List,那么Bar不是Foo聚合的一部分.它是一个单独的实体.

嗯,这就是我在这里看DDD的方式,但我当然不是Eric Evans.


Vij*_*tel 8

拥有聚合根的原因是:

  1. 它们提供对复合实体的受控和定向访问
  2. 他们可以执行规则以确保整个聚合有效

我的看法: 如果你需要选择Bar没有a的对象Foo,请使用a BarRepository.

但是...... 如果你更新了一个Bar,它会破坏它的父级的验证规则Foo怎么办?如果发生这种情况,您应该Bar通过它的父母访问Foo.

但是,如果你需要访问一堆Bar物体(例如,用于批处理作业或报告),你知道Foos不会得到破,继续通过访问它们BarRepository.

请记住,聚合根可以由其他聚合根组成.你可能会发现这Bar是一个聚合根本身,给你一个理由BarRepository:)