DDD基础概念
DDD基础概念
领域与子域
领域(Domain)是系统要解决的业务问题空间。将复杂领域拆分为子域有助于管理复杂性。
// 电商领域划分
// 核心域:订单管理
package com.example.order.domain;
public class OrderService {
// 订单是核心业务逻辑
}
// 支撑域:库存管理
package com.example.inventory.domain;
public class InventoryService {
// 库存支撑订单业务
}
// 通用域:用户认证
package com.example.identity.domain;
public class IdentityService {
// 用户认证是通用能力
}
子域通常分为三类:
- 核心域:业务的核心竞争力,需要重点投入
- 支撑域:支撑核心业务的特定能力
- 通用域:通用的基础设施能力,可外购或使用开源方案
限界上下文
限界上下文(Bounded Context)是领域模型的边界。同一个概念在不同上下文中可能有不同含义。
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 订单上下文 │ │ 支付上下文 │ │ 库存上下文 │
├─────────────────┤ ├─────────────────┤ ├─────────────────┤
│ Product │ │ Product │ │ Product │
│ - 商品信息 │ │ - 商品价格 │ │ - 库存数量 │
│ - 选择数量 │ │ - 支付金额 │ │ - 预留数量 │
│ │ │ │ │ │
│ Order │ │ Payment │ │ Stock │
│ - 订单项 │ │ - 交易记录 │ │ - 库存流水 │
│ - 订单状态 │ │ - 支付状态 │ │ - 库存状态 │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
└──────────────────────┼──────────────────────┘
│
通过明确的接口通信
聚合与聚合根
聚合(Aggregate)是一组相关对象的集合,作为数据修改的基本单元。聚合根(Aggregate Root)是聚合的入口点。
// 订单聚合
@Entity
public class Order {
@Id
private OrderId id;
private OrderStatus status;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
private List<OrderItem> items = new ArrayList<>();
// 聚合根控制内部对象的创建和修改
public OrderItem addItem(ProductId productId, int quantity, Money price) {
OrderItem item = new OrderItem(productId, quantity, price);
items.add(item);
return item;
}
public void removeItem(OrderItemId itemId) {
items.removeIf(item -> item.getId().equals(itemId));
}
public Money calculateTotal() {
return items.stream()
.map(OrderItem::getSubtotal)
.reduce(Money.ZERO, Money::add);
}
}
// OrderItem 是聚合内部对象,不直接对外暴露
@Entity
public class OrderItem {
@Id
private OrderItemId id;
private ProductId productId;
private int quantity;
private Money price;
}
实体与值对象
实体(Entity)具有唯一标识,即使属性相同也是不同的实体。值对象(Value Object)没有唯一标识,通过属性值判断相等性。
// 实体:具有唯一标识
public class Order {
private OrderId id; // 唯一标识
private OrderStatus status;
}
// 值对象:通过属性值判断相等性
@Value
public class Money {
private final BigDecimal amount;
private final Currency currency;
public Money add(Money other) {
if (!this.currency.equals(other.currency)) {
throw new CurrencyMismatchException();
}
return new Money(this.amount.add(other.amount), this.currency);
}
}
@Value
public class Address {
private final String province;
private final String city;
private final String district;
private final String detail;
}
DDD 基础概念为复杂业务系统的建模提供了清晰的指导原则,核心是围绕业务领域构建模型。