4. 识别订单上下文中的聚合根与聚合边界

识别订单上下文中的聚合根与聚合边界 学习卡片

从订单业务规则反推聚合边界

在订单上下文中,聚合根是外部访问聚合内部对象的唯一入口,聚合边界则决定哪些对象必须在同一次事务中保持一致。判断聚合根时,先问三个问题:谁负责维护整体不变量?谁被外部直接引用?谁的生命周期由谁控制?

以订单为例,订单行(OrderLine)不能脱离订单独立存在,收货地址(ShippingAddress)在订单提交后通常作为快照值对象保存。因此,Order 是聚合根,OrderLine 是聚合内部实体,ShippingAddress 是聚合内值对象。外部只能通过 Order 修改订单行或地址,不能绕过 Order 直接操作 OrderLine。

一致性边界与事务边界的取舍

聚合内的一致性由单次事务保证,聚合间的一致性通过领域事件或最终一致性实现。订单聚合内需要强一致的内容包括:订单总金额 = 所有订单行小计之和;订单行数量必须大于 0;订单状态与订单行修改的约束关系。而库存扣减、支付记录、积分累计等跨聚合操作,不应放入订单聚合的同一事务中。

对象角色是否聚合根一致性要求
Order聚合根是维护订单整体不变量
OrderLine内部实体否与 Order 同事务
ShippingAddress值对象否随 Order 快照保存
Payment独立聚合根是通过订单号关联,最终一致
InventoryReservation独立聚合根是通过领域事件异步处理
判断口诀:能独立存在并被外部直接查询的,才可能是聚合根;必须随根一起创建、修改、删除的,放在聚合内部。

订单聚合边界示意

订单聚合边界(单事务强一致) Order(聚合根) orderId · status · totalAmount · createdAt OrderLine(实体) lineId · productId quantity · unitPrice ShippingAddress (值对象) province · city · detail 1..* 1 聚合内不变量 totalAmount = Σ(line.quantity × line.unitPrice) quantity > 0;已支付订单不可删除订单行 Payment 独立聚合根 InventoryReservation 独立聚合根 Customer 独立聚合根 orderId 领域事件 customerId 聚合内强一致引用 跨聚合最终一致引用 聚合边界

落地检查清单

  • 外部对象是否只持有 Order 的引用,而不是 OrderLine 的引用?
  • 修改订单行数量时,是否通过 Order 的方法触发总金额重算?
  • 支付、库存扣减是否通过领域事件异步处理,而非塞进订单事务?
  • ShippingAddress 是否作为值对象随订单快照保存,而不是引用客户档案中的地址实体?
  • 删除订单时,OrderLine 是否随聚合根级联删除?
常见误区:把 OrderLine 设计成独立聚合根,导致订单总金额与订单行数量出现跨聚合不一致;或者把 Payment 强行放入订单聚合,造成事务过大、锁竞争严重。