代码之家  ›  专栏  ›  技术社区  ›  Arnis Lapsa

聚合根问题

  •  16
  • Arnis Lapsa  · 技术社区  · 15 年前

    假设我有两个实体-foo和bar。foo是一个聚合根,包含bar。据我所知,应该是这样的:

    public class Foo{
        private readonly Bar Bar;
    }
    

    我想为用户提供从定义的列表中选择foos栏的功能(并对其进行更改)。

    如果存储库仅用于聚合根,则意味着BAR实体将没有存储库。

    这会导致问题栏在没有参考foo的情况下无法独立创建/更新。

    这是否意味着,尽管没有foo就没有意义,但是bar应该有一个存储库?

    3 回复  |  直到 15 年前
        1
  •  17
  •   queen3    15 年前

    如果要从一个与foo无关的条列表中进行选择,则这不是聚合根。例如,如果没有医嘱,则无法获取医嘱项目列表,因此这是单个聚合根(医嘱),但可以获取要分配给医嘱项目的产品列表,因此产品不是医嘱聚合根的一部分。

    注意,虽然orderitem是order aggregate根目录的一部分,但您仍然可以独立地创建和更新它。但是,如果没有订单,你就不能得到它。对于您的条也是一样的,即使它是foo的一部分,您也可以获取每个(foo.bar)并使用它,或者执行foo.addbar(new bar())。但是如果你需要得到没有foo的列表,那么bar不是foo聚合的一部分。它是一个独立的实体。

    嗯,我就是这么看DDD的,但我当然不是埃里克·埃文斯。

        2
  •  8
  •   Vijay Patel    15 年前

    有聚合根的原因是:

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

    我的拿手: 如果需要选择 Bar 没有的对象 Foo 使用A BarRepository .

    但是… 如果你更新了 酒吧 它破坏了它的父级的验证规则 ?如果可能发生这种情况,您应该访问 酒吧 通过它的父母 .

    但是,如果您需要访问 酒吧 对象(例如批处理作业或报表),以及 知道 那个 Foos 不会被破坏的,继续通过 荒诞的 .

    记住,聚合根可以由其他聚合根组成。你可能会发现 酒吧 是聚合根本身,为 油库 :)

        3
  •  2
  •   Warrior    15 年前

    你确定酒吧需要成为一个实体吗?您是否需要在域中跟踪并更改它?如果您可以将其视为一个值对象,我建议您从服务中获取它,然后将所选值对象“连接”到foo实体。在下拉列表中显示。