You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DDD建模中判定聚合根与子实体归属的最佳实践咨询

聚合根与子实体判断核心依据及场景解决方案

一、判断实体归属的核心标准

  • 业务生命周期一致性:如果实体的存在完全依附于另一实体,主实体删除时该实体必须同步级联删除,且无脱离主实体单独存在的业务场景,优先作为子实体;反之则考虑独立为聚合根。
  • 事务与并发约束:DDD要求单次事务仅修改一个聚合根,若实体的修改频率极高、并发量大,放入主聚合会导致主聚合频繁出现并发冲突,应当独立为聚合根降低锁粒度。
  • 全局引用需求:如果实体需要被其他业务场景直接通过全局唯一ID访问,而非必须通过主聚合导航获取,必须独立为聚合根——子实体仅在所属聚合内有唯一标识,不支持外部直接引用。
  • 业务规则耦合度:如果实体的自身业务校验不需要和主聚合的属性联动校验,可以独立维护自身的不变性规则,可考虑独立为聚合根;如果实体的操作必须关联主聚合的状态、属性做联合校验,适合放在主聚合内作为子实体。

二、Meeting案例的设计逻辑说明

你提到的案例中两个实体的归属设计完全符合上述标准:

  1. MeetingAttendee作为Meeting的子实体,是因为参会者的添加、删除必须关联Meeting的属性做联合校验,比如是否在报名截止时间前、参会人数是否超出会议最大容量,且会议取消时参会资格自动失效,生命周期完全依附于会议,所以放在Meeting聚合内统一管理。
  2. MeetingComment独立为聚合根,核心原因有两点:
    • 评论的增删改操作几乎不需要和会议的核心属性做联动校验,最多仅需校验会议是否已删除,该校验通过最终一致性即可实现,不需要放在同一个事务里;
    • 评论的并发操作频率远高于会议核心信息的修改频率,同时评论本身有单独被引用的场景(比如回复评论、举报评论、点赞评论),如果放在Meeting聚合内,每次操作评论都要锁整个会议聚合,会严重拉高并发冲突概率,影响其他会议操作的性能。
      你之前的猜测方向是正确的,是否可选并不是核心判断依据,主聚合完全可以包含可选的子实体列表。

三、Game场景的建模建议

你可以对照上述4个核心标准,结合实际业务需求选择:

  1. 如果GamePlayer的操作需要和Game的状态强绑定校验,比如添加选手必须校验Game未开赛、参赛人数未超出上限,添加受击记录GamePlayerHits必须校验Game处于进行中,且赛事相关操作并发量不高、没有直接通过ID访问单个GamePlayer的需求,完全可以保留当前设计,将GamePlayer作为Game的子实体管理,Game初始状态下选手列表为空也完全符合聚合设计要求。
  2. 如果存在以下任意一种场景,建议将GamePlayer独立为聚合根,仅保留对Game的ID引用:
    • 有直接通过GamePlayerID查询、操作的业务需求,比如统计特定选手的所有参赛受击数据、单独给选手颁发赛事奖项等;
    • 赛事进行过程中GamePlayerHits的写入并发量极高,放在Game聚合内会导致频繁的并发冲突;
    • 单场赛事的参赛选手量级极大,每次加载Game聚合都要拉取全量选手和受击数据会严重影响性能。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 12:36:04