领域驱动设计(DDD)

DDD 战略设计(限界上下文、子域)与战术设计(聚合、实体、值对象、领域事件),及事件风暴实践方法。

领域驱动设计(DDD)

DDD 是一种以业务领域为核心的软件设计方法,通过统一语言连接业务与技术,解决复杂业务系统的建模难题。

1. DDD 核心思想

┌────────────────────────────────┐
│        统一语言 Ubiquitous     │
│           Language             │
└────────────────────────────────┘
          ↓          ↑
┌────────────────────────────────┐
│        领域模型 Domain Model   │
│  ┌─────┐ ┌─────┐ ┌────────┐  │
│  │实体 │ │值对象│ │ 聚合   │  │
│  └─────┘ └─────┘ └────────┘  │
└────────────────────────────────┘

核心:技术与业务使用同一套语言进行沟通,模型直接反映业务概念。

2. 战略设计

子域(Subdomain)

将复杂业务划分为不同类型:

类型特征示例
核心域竞争优势所在,投入最多电商的推荐算法
支撑子域需要定制但不独特订单管理
通用子域可外购或标准化用户认证、通知服务

限界上下文(Bounded Context)

模型一致性的边界。同一个概念在不同上下文可以有不同的含义。

┌─────────────────┐    ┌─────────────────┐
│  商品上下文      │    │  库存上下文      │
│  Product        │    │  Product        │
│  - name         │    │  - sku          │
│  - description  │    │  - quantity     │
│  - price        │    │  - warehouse    │
│  - category     │    │  - location     │
└─────────────────┘    └─────────────────┘
         ↑                    ↑
    「商品」是销售实体      「商品」是库存单位

上下文映射

┌──────────────┐     合作关系      ┌──────────────┐
│  订单上下文   │ ←─────────────→ │  支付上下文   │
└──────────────┘                 └──────────────┘
        │
        │ 上游/供应商
        ↓
┌──────────────┐
│  库存上下文   │
└──────────────┘
关系含义
合作关系任一方失败影响另一方
客户-供应商上游优先满足下游需求
跟随者复用上游模型
防腐层 (ACL)隔离外部模型影响
开放主机定义清晰接口供外部使用

3. 战术设计

实体(Entity)

有唯一标识且通过标识区分的对象,生命周期中属性可变。

public class Order {
    private OrderId id;          // 唯一标识
    private CustomerId customerId;
    private List<OrderItem> items;
    private OrderStatus status;
    
    public void pay() {          // 业务行为
        if (status != PENDING) throw new IllegalStateException();
        this.status = PAID;
    }
    
    public void ship() { ... }
}

值对象(Value Object)

属性决定身份,不可变,无生命周期概念。

public record Money(BigDecimal amount, Currency currency) {
    public Money add(Money other) {
        if (!this.currency.equals(other.currency)) 
            throw new IllegalArgumentException("Currency mismatch");
        return new Money(this.amount.add(other.amount), this.currency);
    }
}

public record Address(
    String province, 
    String city, 
    String street
) {}

聚合(Aggregate)

一致性边界内的实体与值对象集群。

// Order 是聚合根(Aggregate Root)
public class Order {
    private OrderId id;
    private List<OrderItem> items;  // 聚合内实体
    private ShippingAddress address; // 值对象
    
    // 所有修改通过聚合根
    public void addItem(ProductId productId, int quantity, Money price) {
        items.add(new OrderItem(productId, quantity, price));
        recalculateTotal();
    }
}

聚合设计原则

  • 一个事务只修改一个聚合
  • 聚合根负责维护不变性
  • 聚合间通过 ID 引用(避免直接对象引用)

领域服务(Domain Service)

不属于某个聚合的业务逻辑。

public class PricingService {
    public Money calculateDiscount(Order order, Customer customer) {
        if (customer.isVIP()) {
            return order.getTotal().multiply(0.8);
        }
        return order.getTotal();
    }
}

领域事件(Domain Event)

领域内发生的有意义的事情,实现最终一致性。

public class OrderCreatedEvent {
    private final OrderId orderId;
    private final CustomerId customerId;
    private final Instant occurredOn;
    
    // 用于其他上下文处理后续业务
}

// 发布
public class Order {
    public void create() {
        // ...
        registerEvent(new OrderCreatedEvent(this.id, ...));
    }
}

4. 事件风暴(Event Storming)

Alberto Brandolini 发明的协作建模工作坊。

流程

1. 领域事件(橙色) → OrderCreated, PaymentReceived
2. 命令(蓝色)     → CreateOrder, ReceivePayment
3. 聚合(黄色)     → Order, Payment
4. 策略(紫色)     → 如果支付失败则取消订单
5. 外部系统(粉色) → 支付网关、物流系统

产出物

  • 限界上下文划分
  • 聚合边界
  • 领域事件流
  • 服务拆分候选

5. DDD 分层架构

┌─────────────────────────────────────┐
│  用户接口层(UI/API)                │
│  适配器模式、DTO、输入校验            │
├─────────────────────────────────────┤
│  应用层(Application)               │
│  用例编排、事务控制、事件发布         │
├─────────────────────────────────────┤
│  领域层(Domain)← 核心              │
│  实体、值对象、聚合、领域服务、事件   │
├─────────────────────────────────────┤
│  基础设施层(Infrastructure)        │
│  数据库、消息队列、外部 API 适配      │
└─────────────────────────────────────┘

依赖方向:外层依赖内层,领域层无外部依赖。

6. DDD 与微服务

限界上下文 → 微服务边界
聚合根     → 服务内模块
领域事件   → 服务间通信
防腐层     → API Gateway / Adapter
DDD 概念映射微服务
核心域独立团队维护的核心服务
通用子域共享基础设施服务
限界上下文服务部署边界
领域事件事件驱动架构

总结

层面关键产出工具
战略设计子域划分、限界上下文事件风暴
战术设计聚合、实体、领域服务代码模型
技术实践分层架构、事件驱动框架实现

DDD 的价值不在于严格按照名词定义编码,而在于培养以业务领域为核心思考问题的能力。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「架构」更多文章

  1. 架构评审与技术债管理
  2. SLA/SLO/SLI 与容量规划
  3. 云原生架构模式