架构特征: // 典型贫血实体(仅有数据,无逻辑) public class Order { private Long id; private Date createTime; // 仅有getter/setter }
痛点:
业务逻辑集中在Service层,形成“上帝类”(如OrderService包含数百个方法)
领域概念(如“订单状态流转”)需在Service中通过if-else实现,扩展性差
阶段3:面向业务模型(DDD时代)
核心突破:
充血模型:实体包含业务逻辑
// 充血实体(包含状态变更逻辑) public class Order { private OrderStatus status; public void cancel() { if (status == OrderStatus.NEW) { status = OrderStatus.CANCELED; publishEvent(new OrderCanceledEvent(this)); // 发布领域事件 } } }
领域事件驱动:通过事件解耦跨域逻辑(如订单取消时自动触发库存回滚)
二、领域建模核心:战略设计与战术设计双轮驱动
2.1 战略设计:定义业务边界与领域地图
(1)限界上下文(Bounded Context)
本质:业务语义的“翻译边界”,同一概念在不同上下文可能有不同含义
例:“客户”在电商上下文是“购买者”,在供应链上下文是“供应商”
划分方法:维度核心问题示例(电商系统)业务职责该上下文解决什么核心问题?订单上下文(处理下单、支付、取消)领域专家该上下文由哪个团队负责?订单团队 vs 物流团队数据所有权哪些数据只能由此上下文修改?订单状态仅由订单上下文管理
(2)核心域/子域/通用域
核心域:决定企业竞争力的业务(如电商的“推荐系统”)
子域:支撑核心域的业务(如“用户中心”“支付网关”)
通用域:可复用的公共能力(如“消息通知”“权限系统”)
(3)战略设计图实战案例
说明:
核心域:订单、商品、用户
子域:物流、支付
通用域:消息、权限
箭头表示依赖关系(如订单上下文依赖商品上下文的“商品库存查询”)
2.2 战术设计:从业务概念到代码实体
(1)领域对象四要素
对象类型
定义
特征
示例(订单上下文)
实体(Entity)
有唯一标识,生命周期可变化
标识不变,状态可变(如订单ID固定,状态从“新建”到“完成”)
Order实体
值对象(Value Object)
无唯一标识,仅通过属性值区分
不可变(修改即创建新对象),可整体替换(如地址修改)
Address值对象
领域服务(Domain Service)
不属于任何实体的业务逻辑,处理跨实体操作
无状态,依赖多个实体完成任务(如“计算订单总价”需遍历订单项)
OrderService领域服务
领域事件(Domain Event)
业务状态变更的通知(如订单创建、支付成功)
包含事件类型与相关实体状态,用于触发异步操作(如支付成功后通知物流)
OrderPaidEvent领域事件
(2)聚合与聚合根
聚合(Aggregate):一组相关对象的集合,作为数据修改的最小单元
例:订单聚合包含Order实体、OrderItem实体、DeliveryInfo值对象
聚合根(Aggregate Root):聚合的入口点,外部只能通过聚合根访问内部对象 public class OrderAggregateRoot { private Order order; private List<OrderItem> items; // 外部通过聚合根添加订单项 public void addItem(Product product, int quantity) { items.add(new OrderItem(product.getId(), quantity)); } }
(3)战术设计图深度解析
关键关系:
聚合根(Order)通过组合关系包含OrderItem(订单项)
Order依赖PaymentService(支付领域服务)完成支付
OrderItem引用Product(商品实体,来自商品上下文)
三、技术实现:DDD四层架构的最佳实践
3.1 分层架构详细设计
(1)用户界面层(UI Layer)
职责:
接收前端请求,返回视图或API响应
仅做参数校验与格式转换,不处理业务逻辑
示例代码(Spring MVC): @RestController @RequestMapping("/orders") public class OrderController { private final OrderAppService orderAppService; // 接收DTO,调用应用层 @PostMapping public Result<OrderDTO> createOrder(@RequestBody CreateOrderDTO dto) { Order order = orderAppService.createOrder(dto); return Result.success(convertToDTO(order)); } }
(2)应用层(Application Layer)
职责:
协调领域层完成业务流程
处理跨领域服务调用(如订单创建后调用库存服务扣减库存)
DTO与领域对象的转换
反模式避免:
❌ 禁止在应用层编写核心业务逻辑(如订单状态校验)
✅ 委托给领域层:order.cancel();(调用实体方法)
(3)领域层(Domain Layer)
核心组件:
实体与值对象:封装业务规则
领域服务:处理跨实体逻辑
仓储接口:定义数据操作契约(不涉及具体实现)
// 仓储接口定义(领域层) public interface OrderRepository { Order save(Order order); Order findById(Long id); }
Comments NOTHING