在上一篇《领域建模入门》中,我们讲了:

  • Entity
  • Value Object
  • Aggregate
  • Domain Service
  • Bounded Context
  • 统一语言
  • 状态机
  • 规则归属

但如果只停留在概念层面,领域建模很容易变成“看懂却不会用”。

这一篇,我们用一个 最小订单系统闭环
把领域建模从“概念”落到“结构”。

一、实战目标

我们只实现三个功能:

  1. 创建订单
  2. 支付订单
  3. 取消订单

不引入:

  • MQ
  • Redis
  • 微服务
  • 分布式锁

目标只有一个:

看清规则归属,而不是炫技术。

二、业务规则梳理

先从业务说起,而不是从代码说起。

订单规则

  • 创建时必须有金额
  • 未支付可以取消
  • 已支付不能取消
  • 支付后状态变更

你会发现:

这些规则都属于“订单本身”。
这就是 Domain。

三、模块结构设计

order
 ├─ domain
 ├─ biz
 ├─ repository
 ├─ api
 └─ dto

四、Domain 层建模

1. Value Object:Money

public class Money {
    private final BigDecimal amount;

    public Money(BigDecimal amount) {
        if (amount.compareTo(BigDecimal.ZERO) < 0) {
            throw new IllegalArgumentException("金额不能为负");
        }
        this.amount = amount;
    }

    public BigDecimal getAmount() {
        return amount;
    }
}

特点:

  • 不可变
  • 无 ID
  • 只代表值

2. Entity:Order

public class Order {

    private Long id;
    private Money money;
    private OrderStatus status;

    public Order(Money money) {
        this.money = money;
        this.status = OrderStatus.CREATED;
    }

    public void pay() {
        if (status != OrderStatus.CREATED) {
            throw new RuntimeException("当前状态不可支付");
        }
        status = OrderStatus.PAID;
    }

    public void cancel() {
        if (status == OrderStatus.PAID) {
            throw new RuntimeException("已支付订单不能取消");
        }
        status = OrderStatus.CANCELLED;
    }
}

体现点:

  • 状态机
  • 规则归属
  • 行为内聚

3. 状态枚举

public enum OrderStatus {
    CREATED,
    PAID,
    CANCELLED
}

五、Repository(持久化接口)

public interface OrderRepository {
    void save(Order order);
    Order findById(Long id);
}

关键点:

Domain 不直接写 SQL。

六、Biz 层(流程编排)

public class OrderBizService {

    private OrderRepository repository;

    public void createOrder(BigDecimal amount) {
        Order order = new Order(new Money(amount));
        repository.save(order);
    }

    public void payOrder(Long id) {
        Order order = repository.findById(id);
        order.pay();
        repository.save(order);
    }

    public void cancelOrder(Long id) {
        Order order = repository.findById(id);
        order.cancel();
        repository.save(order);
    }
}

Biz 做的事:

  • 串联流程
  • 调用 Domain
  • 持久化

Biz 不做的事:

  • 不判断规则
  • 不计算金额

七、Controller 层(简化示意)

@RestController
public class OrderController {

    private OrderBizService service;

    @PostMapping("/create")
    public void create(BigDecimal amount) {
        service.createOrder(amount);
    }
}

Controller 只负责:

输入输出,不负责业务。

八、这个实战体现了哪些建模点?

知识点 体现位置
Entity Order
Value Object Money
Aggregate Order
状态机 OrderStatus
规则归属 pay / cancel
Repository OrderRepository
Biz 编排 OrderBizService

九、为什么不加 MQ / Redis?

因为这篇的目标不是“系统复杂度”,
而是:

规则清晰度。

一旦加太多技术,读者会迷失。

十、实战结论

你会发现:

Controller 没有业务逻辑

Biz 没有规则判断

Domain 没有 SQL

Repository 没有业务规则

这就是领域建模的落地效果。

十一、实战口诀

可以记这四句:

规则进 Domain
流程进 Biz
数据进 Repository
输入输出给 Controller

做到这四点,
你的系统就从“堆代码”进化为“有结构”。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐