产品购后业务流程:应用服务、领域服务还是领域事件选型?
三种实现"购买完成后更新库存+生成发票"业务规则的方案对比
方案一:应用服务依次调用UpdateInventory()和GenerateInvoice()
优点
- 逻辑直白,一眼就能看明白流程是先扣库存再生成发票,排查问题顺着调用链找就行
- 调整灵活,后续要改步骤顺序或者加个额外操作,直接在应用服务里改,不用动领域层代码
- 职责边界清楚,应用服务管流程编排,领域层只负责单一的业务操作
缺点
- 业务规则容易"跑"到应用层,要是以后业务要求必须先开票再扣库存,就得改应用服务,违背了DDD把业务规则封装在领域层的原则
- 重复代码风险高,要是多个应用场景都需要这套流程,每个地方都得写一遍调用逻辑,维护起来麻烦
- 事务不好控制,要是两个操作不在同一个事务里,可能出现库存扣了但发票没生成的不一致情况
方案二:领域服务中封装调用UpdateInventory()和GenerateInvoice()
优点
- 业务规则完全封在领域层,应用层只需要调用一个领域服务方法,不用管内部怎么执行,符合DDD的核心思路
- 避免重复代码,所有需要这套流程的地方都调用同一个方法,改一次全生效
- 事务保障更靠谱,领域服务内部可以把两个操作放在同一个事务里,数据一致性有保障
缺点
- 领域服务容易变臃肿,要是以后再加关联操作(比如更新销售报表),堆到领域服务里会变成"什么都管"的大杂烩
- 调试成本高,排查问题得深入领域服务内部,链路比应用服务直接调用长
- 灵活性不足,要是某些特殊场景需要跳过其中一个操作,得给领域服务加参数做判断,越改越复杂
方案三:调用UpdateInventory(),通过领域事件触发生成发票
优点
- 完全解耦两个操作,库存更新和发票生成各干各的,互不干扰,职责单一
- 扩展性拉满,以后要加其他操作(比如给用户发购买通知、更新销售统计),只要加个新的事件监听器就行,不用改原有代码
- 适合异步场景,发票生成可以后台异步处理,不拖慢主流程的响应速度
缺点
- 流程不直观,新手很难一下子搞懂"库存更新怎么就触发开票了",排查问题得跟踪整个事件流转链路
- 数据一致性依赖事件可靠性,要是事件丢了,就会出现库存扣了但发票没生成的情况,得额外做重试、死信队列这些保障机制
- 开发维护成本高,得搭建事件总线,还要处理异步逻辑的各种异常(比如重试失败、消息重复)
内容的提问来源于stack exchange,提问作者francis d
相关产品推荐
相关产品推荐

