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

DDD实践:创建聚合时如何校验关联聚合的状态?

问题

在同一个限界上下文内存在三个聚合:

  • PhoneAggregate
  • ServiceCenterAggregate
  • ServiceWorkAggregate

ServiceWorkAggregate通过ID关联PhoneAggregate和ServiceCenterAggregate。创建新的ServiceWorkAggregate时,前端会发送如下POST请求:

{
    "phone_id": "uuid",
    "servicecenter_id": "uuid"
}

不能直接通过这些ID创建聚合,必须执行校验:至少要确认这些UUID是有效的实体ID,还可能需要基于PhoneAggregate和ServiceCenterAggregate的当前状态执行业务逻辑校验。

现有三种思路,需要确定最优实现方式:

  1. 让ServiceWorkAggregate的应用服务或领域服务引入三个聚合的仓库。
    • 子问题:是由应用服务仅传递ID给领域服务,由领域服务加载聚合并完成所有校验(因涉及业务逻辑)?还是由应用服务先获取聚合,再传递给领域服务?
  2. 将关联聚合视为值对象,在ServiceWorkAggregate中用值对象Repairable和ServiceLocation替代phone_id和servicecenter_id字段,这两个值对象是对应聚合的不可变副本(从同一张表获取等),此时只需在ServiceWork应用服务中引入一个仓库。
  3. 是否有更优的实现方式?
最优实现方案分析

思路1的合理性与最佳实践

这是DDD中处理跨聚合校验的常规方案,核心原则是领域逻辑归领域服务,应用服务只做编排:

  • 正确的做法是应用服务仅传递ID给领域服务,由领域服务完成校验。原因很简单:业务校验逻辑属于领域规则,必须封装在领域层内,不能泄露到应用层。如果让应用服务先加载聚合再传递,会导致领域逻辑分散,后续规则变更时要同时修改应用层和领域层,违反单一职责。
  • 具体流程:应用服务接收请求中的phone_id和servicecenter_id,调用领域服务的createServiceWork方法并传入这两个ID;领域服务从对应的仓库加载PhoneAggregate和ServiceCenterAggregate,先校验ID有效性(加载失败即无效),再执行业务规则校验(比如该手机是否处于可维修状态、服务中心是否有空闲工位等);校验通过后,领域服务创建ServiceWorkAggregate并返回给应用服务,由应用服务调用仓库保存。
  • 注意:领域服务可以是专门的ServiceWorkDomainService,也可以是ServiceWorkAggregate的静态工厂方法,只要保证校验逻辑在领域层即可。

思路2的局限性

把关联聚合做成值对象副本的方式,只适用于不需要实时校验关联聚合状态的场景:

  • 问题在于值对象是不可变副本,无法反映关联聚合的实时状态。比如如果创建服务工单时需要校验手机是否已被注销、服务中心是否已停业,用副本就无法获取最新状态,会导致校验失效。
  • 另外,这种方式会增加数据冗余,后续关联聚合的信息变更时,副本无法同步,除非额外做事件同步,反而增加复杂度。所以仅当关联聚合的状态不会影响ServiceWorkAggregate的创建规则时,才适合用这种方式。

更优的补充方案:基于领域事件的前置校验(可选)

如果系统对性能要求极高,不想每次创建工单都加载两个聚合,可以提前通过领域事件维护一个校验缓存:

  • 比如PhoneAggregate的状态变更时(如从"正常"变为"注销"),发布领域事件,由专门的服务更新缓存中该手机的可维修状态;同理维护服务中心的可用状态缓存。
  • 创建工单时,领域服务先查缓存做快速校验,校验通过后再创建聚合,后续可以通过后台异步任务做最终一致性校验(如果缓存和实际数据不一致,触发补偿逻辑)。
  • 但这种方案适合高并发场景,引入了最终一致性的复杂度,普通场景下思路1的同步校验已经足够。

最终结论

优先选择思路1的第一种子方案:由应用服务传递ID,领域服务加载关联聚合并完成所有校验。这种方案严格遵循DDD分层原则,保证领域逻辑的内聚性,后续维护和扩展都更清晰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 17:35:36