第二十二课:领域建模实战——订单系统最小闭环(实战篇)
本文通过一个最小订单系统案例,演示如何将领域建模从概念落地到代码结构。系统仅实现创建、支付和取消订单三个核心功能,聚焦规则归属而非技术复杂度。采用分层设计:Domain层封装订单实体、金额值对象和状态规则;Repository处理持久化;Biz层负责流程编排;Controller仅处理输入输出。案例展示了领域建模的关键原则:业务规则内聚在Domain层,流程控制由Biz层处理,数据访问归Repos
·
在上一篇《领域建模入门》中,我们讲了:
- Entity
- Value Object
- Aggregate
- Domain Service
- Bounded Context
- 统一语言
- 状态机
- 规则归属
但如果只停留在概念层面,领域建模很容易变成“看懂却不会用”。
这一篇,我们用一个 最小订单系统闭环,
把领域建模从“概念”落到“结构”。
一、实战目标
我们只实现三个功能:
- 创建订单
- 支付订单
- 取消订单
不引入:
- 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
做到这四点,
你的系统就从“堆代码”进化为“有结构”。
更多推荐

所有评论(0)