2023 年,我主导了一个电商中台的 DDD 重构项目。从最初的「大泥球」单体架构到最终的领域驱动设计落地,我们踩了无数的坑。这篇文章不谈理论,只讲实战中用血泪换来的五条聚合根设计教训。
背景:那个让我们失眠的订单系统
老系统是一个典型的「上帝类」架构——OrderService 有 8000 多行代码,一个 createOrder 方法就包含了库存扣减、优惠券核销、积分计算、物流单创建等 12 个领域的逻辑。任何一个小改动都可能引发蝴蝶效应。
我们决定用 DDD 重构。但理论上的 DDD 和工程实践之间的鸿沟,远比教科书中描述的要深。
教训一:聚合根不是实体,是一致性边界
最初的设计中,我们把 Order(订单)设计成了一个巨大的聚合根,里面包含了订单项、收货地址、支付信息、物流跟踪、发票信息等所有关联实体。
// 错误示范:上帝聚合根
public class Order {
private OrderId id;
private List<OrderItem> items; // 订单项
private ShippingAddress address; // 收货地址
private PaymentInfo payment; // 支付信息
private List<LogisticsRecord> logistics;// 物流跟踪
private InvoiceInfo invoice; // 发票信息
private CouponUsage couponUsage; // 优惠券使用记录
private List<OrderRemark> remarks; // 订单备注
// 一个方法改了 7 个实体的状态...
public void confirmOrder() {
// 验证库存、验证地址、创建支付单、生成物流单...
}
}
问题很快暴露了: