You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

DDD中聚合与聚合根是否需实现为独立类?示例求证

关于DDD聚合与聚合根实现的解惑

我懂这种找不到靠谱DDD代码示例的挫败感——DDD的概念本身就偏抽象,落地时确实容易纠结这些细节。咱们先理清核心概念,再逐个拆解你给出的三种实现方式:

核心概念先明确

在DDD里,聚合是一组紧密关联的实体、值对象形成的边界集群,目的是把需要一起保持一致性的对象打包在一起;而聚合根是这个集群的唯一入口和管理者,负责维护整个聚合的不变量,外部只能通过聚合根与聚合内的对象交互。聚合本身是一个边界概念,不一定需要对应一个单独的类。

三种实现方式的判断

1. 独立类实现

class Aggregate { 
  private Entity aggregateRootEntity; 
  //维护不变量的方法 
}

这种实现不太符合DDD的常规实践。聚合本质是边界,不是一个需要实例化的类。把聚合做成包裹聚合根的外层类,会增加不必要的抽象层级,还容易把聚合根的核心职责(维护不变量、协调内部对象)转移到外层,违背了聚合根作为交互入口的设计意图。实际项目里很少这么写。

2. 由聚合根类代表聚合

class AggregateRootEntity { 
  //id、字段、值对象引用、其他实体引用 
  //维护不变量的方法 
}

这是最常见也最符合DDD规范的实现方式。实际开发中,我们不需要专门定义一个名为Aggregate的类,而是用聚合根类来代表整个聚合的边界。聚合根内部持有属于该聚合的其他实体、值对象,所有对聚合内部的修改操作都必须通过聚合根的方法来执行,以此确保整个聚合的不变量始终被满足。比如订单作为聚合根,内部包含订单项(实体)、收货地址(值对象),添加订单项、修改地址都得调用订单的方法,不能直接操作内部对象。

3. 满足条件的实体作为聚合

//这是聚合:
class Entity { 
  private List<ValueObject> valueObjects; 
  //id、字段 
  //维护不变量的方法 
}

这个说法不完全准确,但如果这个实体承担了聚合根的全部职责,那它所在的集群就是一个合法的聚合。要注意:聚合是一个集群,哪怕这个集群里只有这个实体和它的值对象(最简单的聚合形态),它也是一个聚合。但关键是这个实体必须是聚合根——拥有全局唯一ID,负责维护整个聚合的不变量,并且是外部唯一的交互入口。如果只是一个普通实体(比如没有全局ID,只能通过其他聚合根访问),那它不能单独作为聚合。

实践小建议

实际项目里,别纠结“要不要写Aggregate类”,重点放在聚合边界的划分不变量的维护上。只要确保:

  • 聚合内的对象始终保持一致性
  • 外部只能通过聚合根与聚合交互
  • 聚合根负责所有内部修改操作
    那就是正确的DDD聚合实现。

内容的提问来源于stack exchange,提问作者Vuk Djapic

火山引擎 最新活动