DDD:聚合根问题
假设我有 2 个实体 - Foo 和 Bar。 Foo 是聚合根并包含 Bar。据我了解,它应该看起来像这样:
public class Foo{
private readonly Bar Bar;
}
我想为用户提供从定义的列表中选择 Bars for Foos 的功能(并更改它)。
如果存储库应该仅用于聚合根,则意味着将不存在 Bar 实体的存储库。
这会导致问题 - 如果不引用 Foo,则无法独立创建/更新 Bar。
这是否意味着 Bar 应该有一个存储库,尽管没有 Foo 就没有任何意义?
Let's say i got 2 entities - Foo and Bar. Foo is an aggregate root and contains Bar. As far as i understand, it should look like this:
public class Foo{
private readonly Bar Bar;
}
I want to provide functionality for users to choose Bars for Foos from a defined list (and change it).
If repositories are supposed to be for aggregate roots only it means that there will be no repository for Bar entity.
This leads to problem - Bar can't be created/updated independently without a reference to Foo.
Does that mean that Bar is supposed to have a repository despite that it has no meaning without a Foo?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您想从不与 Foo 关联的 Bar 列表中进行选择,那么这不是聚合根。例如,您无法获取没有订单的 OrderItems 列表,因此这是单个聚合根 (Order),但您可以获取要分配给 OrderItems 的产品列表,因此 Product 不是订单聚合根的一部分。
请注意,虽然 OrderItem 是 Order 聚合根的一部分,但您仍然可以独立创建和更新它。但是,如果不参考订单,您就无法获取它。对于 Bar 来说也是如此,即使它是 Foo 的一部分,您也可以获取 every(Foo.Bars) 并使用它,或者执行 Foo.AddBar(new Bar()) 。但如果您需要获取没有 Foo 的 List,则 Bar 不是 Foo 聚合的一部分。它是一个独立的实体。
嗯,这就是我对 DDD 的看法,但当然我不是 Eric Evans。
If you want to select from a list of Bars where they're not associated with Foo, then this is not an aggregate root. For example, you can't get list of OrderItems without their Order, so this is single aggregate root (Order), but you can get list of Products to assign to OrderItems, so Product is not part of the Order aggregate root.
Notice that while OrderItem is part of Order aggregate root, you can still create and update it independently. But, you cannot get it without reference to Order. Same for your Bar, even if it was part of Foo, you could get each(Foo.Bars) and work with it, or do Foo.AddBar(new Bar()). But if you need to get List without Foo, Bar is not part of Foo aggregate. It is a separate entity.
Well, that's how I see DDD here, but I'm not Eric Evans, of course.
拥有聚合根的原因是:
我的看法:
如果您需要选择没有
Foo
的Bar
对象,请使用BarRepository
。但是...
如果您更新
Bar
,并且它违反了其父Foo
的验证规则,该怎么办?如果发生这种情况,您应该通过其父Foo
访问Bar
。但是,如果您需要访问一堆
Bar
对象(例如,用于批处理作业或报告),并且您知道Foos
获胜不要被破坏,继续通过BarRepository
访问它们。请记住,聚合根可以由其他聚合根组成。您可能会发现
Bar
本身就是一个聚合根,这为您提供了BarRepository
的理由:)The reasons for having Aggregate roots are:
My take:
If you need to select
Bar
objects without aFoo
, use aBarRepository
.But...
What if you update a
Bar
, and it breaks a validation rule for it's parentFoo
? If this could happen, you should accessBar
via it's parentFoo
.If, however, you need to access a bunch of
Bar
objects (e.g for a batch job or report), and you know thatFoos
won't get broken, go ahead and access them viaBarRepository
.Remember that aggregate roots can be composed of other aggregate roots. You may discover that
Bar
is an aggregate root itself, giving you justification for aBarRepository
:)您确定 Bar 需要是一个实体吗?您是否需要在域中跟踪并更改它?如果您可以将其视为值对象,我建议您从服务中获取它,然后将所选值对象“连接”到 Foo 实体。通过下拉列表瞬间。
Are you sure that Bar need to be a entity? Do you have the need to track it and change it in the domain? If you can look at it as a value object, I would suggest that you fetch it from a service and then "connect" the selected value object to the Foo entity. For instants through a dropdown list.