订单系统建模思考
本文是对于订单建模的一点思考整理,里面应用一些对领域驱动设计的思考,默认读者对于领域概念有一些基本了解。
基本元素
交易最早是通过以物易物的方式来交换,后面产生等价通用物品即货币。交易上下文领域对象包括:
1 | 顾客 Consumer |
对于交易一句话描述就是,顾客在商家那里通过等价货币购换取了货物。
上面描述的四种领域对象作为领域实体,每一种领域实体通过 key 组合来确定实体的唯一性,ext 是值对象,用来描述实体。对应的实体描述如下:
1 | Consumer: |
状态事件抽象
订单状态变更命令通用流程抽象如下图,一个领域命令被触发后,首先进行状态变更前的资格校验事件回调,所有校验方均校验通过后方可进行后续处理,将交易修改为对应状态,状态修改后发布对应的状态变更事件,经由事件总线发布事件,所有监听方进行后续处理。一个领域命令执行结束。此流程可以套用到任何状态变更命令。
状态变化通过领域命令发起 command
,首先进行 BeforeOperating
操作前的处理,每一个命令都定义了事件的资格校验 qualification
接口,实现接口的可能是子域内处理,比如下单的库存校验,优惠校验等,也可能是具体业务的校验,需要实现资格校验接口。通过后进行事务性的状态变更操作 updateState
,操作后进行状态变更后 AfterOperating
的事件发布,由各个业务监听进行后续处理。这样处理方便业务逻辑解耦,订单子域专注于订单状态的管理。
对应到订单系统,对于订单状态和物流状态节点以及领域事件如下表示:
订单状态
- 已创建 CREATE(COMMIT)
- 已支付 PAID
- 已退款 REFUND(REFUNDING)
- 已关闭 CLOSED
物流状态
- 待发货 WAITING
- 已发货 DELIVERED
- 已收货 RECEIVED
- 已退货 RETURN
领域命令
- 创建订单 createOrder
- 超时关单 closeOrder
- 支付订单 payOrder
- 申请退款 refundOrder
- 订单履约 deliverOrder
- 商家发货 deliverGoods
- 用户收货 receiveGoods
- 用户退货 returnGoods
子域拆分
订单子域的拆分也是业务职责的拆分,订单管理和物流管理是相对独立的两个模块,订单主要关注收款履约退款,物流主要关注用户的收退货状态,所以整个交易域的订单和物流会被拆分成两个子域。
订单事件举例
订单创建命令,首先对注册的条件回调方进行回调,确认当前的购买资格,通过后进行事务性的订单创建,创建后进行订单已创建的事件发布,所有监听方接收到消息后进行分析处理。