导航

理解DDD中的实体、值对象、聚合根

Posted on 2022-12-18 08:35  蝈蝈俊  阅读(2934)  评论(0编辑  收藏  举报

在领域模型映射成程序设计时,最基础的领域对象会是实体、值对象、聚合根这些。

实体(Entity)

通过一个唯一标识字段来区分真实世界中的每一个个体的领域对象。

实体 = 唯一身份标识 + 可变性

在实体的生命周期内,无论其如何变化,其仍旧是同一个实体。

  • 实体本身是有状态的;
  • 实体有严谨的生命周期;
  • 实体本身会体现出相应的业务行为;
  • 业务行为会被实体属性/状态造成影响和改变。

例如:公安系统的身份信息录入,对于人的身份信息可以认为是实体,因为每个人是独一无二,且具有唯一标识,且随着时间的推移人的年龄,身高,外貌会进行变化,但是标识不变。

值对象(ValueObject)

代表的是真实世界中哪些一成不变、本质性的事物,这样的领域对象叫做“值对象”。

当一个对象用于对事物进行描述而没有唯一标识时,它被称为值对象。

值对象 = 值 + 对象
      = 将一个值用对象的方式进行表述,
        来表达一个具体的固定不变的概念。 

值对象

  • 本身无状态,不可变,并且不分配具体的标识。
  • 本身无生命周期,也不会产生独立行为

例如:颜色信息,我们只需要知道

{ 
    "name":"黑色",
    "css":"#000000"
}

这样的值信息就能够满足要求,这避免了我们对其标识追踪带来的系统复杂性。

在实践中,需要保证值对象创建后就不能被修改,即不允许外部载修改其属性。

比如:订单上下问中如果只关注下单时商品信息的快照,那么就商品对象视为值对象是很好的选择。

可变性是实体的特点,不变性是值对象的本质。

聚合根(AggregateRoot)

是一组相关对象的集合,作为一个整体被外界访问,聚合根就是这个聚合的根节点

领域模型内的实体和值对象就好比个体,而能让实体和值对象协同工作的组织就是聚合,它用来确保这些领域对象在实现共同的业务逻辑时,能保证数据的一致性。把聚合比作组织,那聚合根就是这个组织的负责人。聚合根也称为根实体,它不仅是实体,还是聚合的管理者

  1. 首先它作为实体本身,拥有实体的属性和业务行为,实现自身的业务逻辑。
  2. 其次它作为聚合的管理者,在聚合内部负责协调实体和值对象按照固定的业务规则协同完成共同的业务逻辑。
  3. 最后在聚合之间,它还是聚合对外的接口人以聚合根ID关联的方式接受外部任务和请求,在上下文内实现聚合之间的业务协同。也就是说,聚合之间通过聚合根ID关联引用,如果需要访问其它聚合的实体,就要先访问聚合根,再导航到聚合内部实体,外部对象不能直接访问聚合内实体。

例子

下图以保险的投保业务场景为例:

说明:

  • 标的是指合同当事人之间存在的权利义务关系。

区别总结

聚合根的特点:

聚合根是实体,有实体的特点,具有全局唯一标识,有独立的生命周期。

一个聚合只有一个聚合根,聚合根在聚合内对实体和值对象采用直接对象引用的方式进行组织和协调,聚合根与聚合根之间通过 ID 关联的方式实现聚合之间的协同。

实体的特点:

有 ID 标识,通过 ID 判断相等性,ID 在聚合内唯一即可。

状态可变,它依附于聚合根,其生命周期由聚合根管理。

实体一般会持久化,但与数据库持久化对象不一定是一对一的关系。

实体可以引用聚合内的聚合根、实体和值对象。

值对象的特点:

无 ID,不可变,无生命周期,用完即扔。

值对象之间通过属性值判断相等性。

它的核心本质是值,是一组概念完整的属性组成的集合,用于描述实体的状态和特征。

值对象尽量只引用值对象。