DEV Community

架构师小白
架构师小白

Posted on

领域驱动设计(DDD)实战指南:从理论到代码落地

什么是领域驱动设计?

领域驱动设计(Domain-Driven Design,简称DDD)是一种软件开发方法论,由Eric Evans在2003年提出。它的核心思想是:将软件系统的设计与业务领域(Domain)紧密绑定,通过深入理解业务领域来构建更加精确、有价值的软件模型。


DDD 的核心概念

1. 通用语言(Ubiquitous Language)

团队所有成员(开发人员、业务专家、产品经理)使用统一的语言来描述业务概念,避免沟通歧义。

2. 限界上下文(Bounded Context)

将大型系统拆分为多个独立的边界,每个边界内部有自己的领域模型和通用语言。

3. 核心域(Core Domain)

识别系统中最重要的业务部分,集中资源和精力优先构建。


DDD 的核心构建块

实体(Entity)

具有唯一标识的对象,其身份在生命周期内保持不变。

public class Order {
    private final OrderId id;  // 唯一标识
    private Money totalAmount;
    private List<OrderItem> items;

    public void addItem(Product product, int quantity) {
        // 业务逻辑验证
        items.add(new OrderItem(product, quantity));
        recalculateTotal();
    }
}
Enter fullscreen mode Exit fullscreen mode

值对象(Value Object)

没有唯一标识的属性集合,一旦创建就不可变。

public record Money(BigDecimal amount, Currency currency) {
    public Money add(Money other) {
        if (!this.currency.equals(other.currency)) {
            throw new CurrencyMismatchException();
        }
        return new Money(this.amount.add(other.amount), currency);
    }
}
Enter fullscreen mode Exit fullscreen mode

聚合根(Aggregate Root)

管理聚合内部所有对象的生命周期,保证业务规则的一致性。

领域服务(Domain Service)

当业务逻辑不属于任何实体或值对象时,创建领域服务来承载。

仓储(Repository)

封装数据访问逻辑,提供领域模型的对象集合接口。


DDD 实战:订单系统示例

战略设计:划分限界上下文

┌─────────────────────────────────────────┐
│           订单系统 (Order Context)       │
├─────────────────────────────────────────┤
│  聚合: Order                            │
│  实体: Order, OrderItem                 │
│  值对象: Money, Address, ProductInfo    │
│  领域服务: OrderPricingService           │
└─────────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

战术设计:代码实现

// 聚合根示例
public class Order implements AggregateRoot {
    private OrderId id;
    private CustomerId customerId;
    private List<OrderItem> items;
    private OrderStatus status;

    // 工厂方法
    public static Order create(CustomerId customerId) {
        Order order = new Order();
        order.id = new OrderId(UUID.randomUUID());
        order.customerId = customerId;
        order.items = new ArrayList<>();
        order.status = OrderStatus.DRAFT;
        return order;
    }

    // 领域行为
    public void addProduct(Product product, int quantity) {
        validateNotFinalized();
        items.add(new OrderItem(product.getId(), product.getPrice(), quantity));
    }

    public void submit() {
        validateCanSubmit();
        this.status = OrderStatus.SUBMITTED;
        // 领域事件
        addDomainEvent(new OrderSubmittedEvent(this));
    }

    private void validateCanSubmit() {
        if (items.isEmpty()) {
            throw new IllegalStateException("订单不能为空");
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

DDD 的适用场景

适合使用 DDD 的场景:

  • 复杂业务领域(金融、医疗、ERP)
  • 需要长期维护和演进的大型系统
  • 团队具备较强的业务理解能力

不适合使用 DDD 的场景:

  • 简单的 CRUD 应用
  • 快速原型验证
  • 业务逻辑简单的数据展示系统

总结

领域驱动设计不仅仅是一套技术,更是一种思维方式:

  1. 以业务为核心 - 深入理解业务领域,而不是盲目套用技术
  2. 持续迭代 - DDD 是一个持续学习和改进的过程
  3. 团队协作 - 建立通用语言,促进团队沟通

"领域驱动设计的真正价值不在于代码,而在于对业务的深刻理解。"

Top comments (0)