DDD:聚合根问题

发布于 2024-08-06 08:14:38 字数 320 浏览 0 评论 0原文

假设我有 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 技术交流群。

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

发布评论

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

评论(3

囍笑 2024-08-13 08:14:38

如果您想从不与 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.

缘字诀 2024-08-13 08:14:38

拥有聚合根的原因是:

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

我的看法:
如果您需要选择没有 FooBar 对象,请使用 BarRepository

但是...
如果您更新 Bar,并且它违反了其父 Foo 的验证规则,该怎么办?如果发生这种情况,您应该通过其父 Foo 访问 Bar

但是,如果您需要访问一堆 Bar 对象(例如,用于批处理作业或报告),并且您知道 Foos 获胜不要被破坏,继续通过 BarRepository 访问它们。

请记住,聚合根可以由其他聚合根组成。您可能会发现 Bar 本身就是一个聚合根,这为您提供了 BarRepository 的理由:)

The reasons for having Aggregate roots are:

  1. They provide controlled and directed access to composite entities
  2. They can enforce rules to ensure that the entire aggregate is valid

My take:
If you need to select Bar objects without a Foo, use a BarRepository.

But...
What if you update a Bar, and it breaks a validation rule for it's parent Foo? If this could happen, you should access Bar via it's parent Foo.

If, however, you need to access a bunch of Bar objects (e.g for a batch job or report), and you know that Foos won't get broken, go ahead and access them via BarRepository.

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 a BarRepository :)

养猫人 2024-08-13 08:14:38

您确定 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.

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