代码之家  ›  专栏  ›  技术社区  ›  Dinah SLaks

什么是聚合根?

  •  380
  • Dinah SLaks  · 技术社区  · 16 年前

    我正在努力了解如何正确使用存储库模式。聚合根的核心概念不断出现。在搜索Web和堆栈溢出以获得关于聚合根的帮助时,我一直在寻找关于它们的讨论以及指向那些应该包含基本定义的页面的死链接。

    在存储库模式的上下文中, 什么是聚合根?

    10 回复  |  直到 8 年前
        1
  •  260
  •   Jeff Sternal    16 年前

    在存储库模式的上下文中,聚合根是客户机代码从存储库加载的唯一对象。

    存储库封装了对子对象的访问——从调用者的角度来看,它会自动加载子对象,无论是在加载根对象的同时,还是在实际需要时(就像延迟加载一样)。

    例如,您可能有 Order 对象,它封装对多个 LineItem 物体。您的客户端代码永远不会加载 线性项 直接的对象,只是 秩序 包含它们的,它将是域中该部分的聚合根。

        2
  •  173
  •   jason    16 年前

    从伊万斯DDD:

    聚合是关联对象的集群,我们将其视为数据更改的一个单元。每个聚合都有一个根和一个边界。边界定义了聚合中的内容。根是聚合中包含的单个特定实体。

    还有:

    根是聚合中唯一允许外部对象保存对[]引用的成员。

    这意味着聚合根是唯一可以从存储库加载的对象。

    示例是包含 Customer 实体和 Address 实体。我们将永远无法访问 地址 直接来自模型的实体,因为如果没有关联的 顾客 .所以我们可以这么说 顾客 地址 一起形成一个集合 顾客 是聚合根。

        3
  •  72
  •   Marcin Szymczak    10 年前

    聚合根是简单思想的复杂名称。


    总体思路

    设计良好的类图封装了它的内部。访问此结构的点称为 aggregate root

    解决方案的内部可能非常复杂,但此层次结构的用户将只使用 root.dosomethingwhichhasbusinessHe意义().


    示例

    检查这个简单的类层次结构

    你想怎么开车?选择更好的API

    选项A(它只是以某种方式起作用):。

    car.ride();
    < /代码> 
    
    

    选项B(用户可以访问类内部函数):。

    if(car.gettires().getusagelevel()<car.acceptable_tire_usage)
    用于(wheel w:car:getwheels()){
    W)()
    }
    }
    < /代码> 
    
    

    如果你认为选择A更好,那恭喜你。您得到了背后的主要原因aggregate root


    聚合根封装了多个类。您只能通过主对象操作整个层次结构。

    访问此结构的点称为aggregate root.

    enter image description here

    解决方案的内部可能非常复杂,但此层次结构的用户将只使用root.doSomethingWhichHasBusinessMeaning().


    例子

    检查这个简单的类层次结构 enter image description here

    你想怎么开车?选择更好的API

    选项A(它只是以某种方式工作):

    car.ride();
    

    选项B(用户可以访问类内部消息):

    if(car.getTires().getUsageLevel()< Car.ACCEPTABLE_TIRE_USAGE)
        for (Wheel w: car:getWheels()){
            w.spin();
        }
    }
    

    如果你认为选择A更好,那恭喜你。你知道背后的主要原因聚合根.


    聚合根封装了多个类。您只能通过主对象操作整个层次结构。

        4
  •  31
  •   Dinah SLaks    16 年前

    假设你有一个计算机实体,这个实体也不能没有它的软件实体和硬件实体。这些形成 Computer 聚合,域的计算机部分的小型生态系统。

    聚合根是聚合中的母舰实体(在我们的例子中 电脑类 )通常情况下,存储库只与聚合根的实体一起工作,而该实体负责初始化其他实体。

    将聚合根视为聚合的入口点。

    C代码:

    public class Computer : IEntity, IAggregateRoot
    {
        public Hardware Hardware { get; set; }
        public Software Software { get; set; }
    }
    
    public class Hardware : IEntity { }
    public class Software : IValueObject { }
    
    public class Repository<T> : IRepository<T> where T : IAggregateRoot {}
    

    请记住,硬件也可能是ValueObject(本身不具有标识),请仅将其作为示例。

        5
  •  11
  •   Captain Kenpachi    12 年前

    如果您遵循数据库优先的方法,那么聚合根通常是一个多关系的1侧的表。

    最常见的例子是一个人。每个人都有多个地址、一个或多个工资单、发票、CRM条目等。情况并非总是如此,而是9/10倍。

    我们目前正在开发一个电子商务平台,基本上我们有两个共同的根源:

    1. 客户
    2. 卖家

    客户提供联系信息,我们为他们分配交易,交易获取行项目等。

    卖家销售产品,有联系人,关于我们的页面,特别优惠等。

    这些由客户和卖方存储库分别处理。

        6
  •  8
  •   Otávio Décio    16 年前

    从A broken link :

    在聚合中有一个聚合根。聚合根是聚合中所有其他实体和值对象的父实体。

    存储库对聚合根进行操作。

    还可以找到更多信息 here .

        7
  •  7
  •   Ibrahim Malluf    9 年前
    Dinah:

    在存储库的上下文中,聚合根是没有父实体的实体。它包含零个、一个或多个子实体,这些实体的存在依赖于其标识的父实体。这是存储库中的一对多关系。这些子实体是普通聚合。

    其存在取决于父母的身份。这是存储库中的一对多关系。这些子实体是简单的聚合。

    enter image description here

        8
  •  3
  •   palash140    10 年前

    骨料 意思是收集某物。
    就像树的顶端节点,从那里我们可以访问 <html> 网页文档中的节点。
    博客类比,一个用户可以有很多帖子,每个帖子可以有很多评论。因此,如果我们获取任何用户,那么它可以充当 访问所有相关的帖子以及这些帖子的进一步评论。这些都被称为收藏品或 聚集的

        9
  •  0
  •   Henry H.    10 年前

    在Erlang中,一旦聚合由状态内部的数据结构组成,而不是由OO组成,就不需要区分聚合。参见一个例子: https://github.com/bryanhunter/cqrs-with-erlang/tree/ndc-london

        10
  •  0
  •   Alireza Rahmani Khalili    8 年前

    聚合是通过限制其访问思想聚合根来保护不变量和强制一致性的地方。不要忘记,聚合应该根据您的项目业务规则和不变量进行设计,而不是数据库关系。不应插入任何存储库,不允许进行任何查询。

    推荐文章