领域驱动设计(DDD)疑问:服务应调用其他服务还是跨域调用Repository?
DDD分层调用逻辑解答
核心结论
Customer Service 应当调用 User Service 的更新方法,禁止直接调用 User Repository
具体原因
- 符合DDD的领域边界约束:Repository 仅对所属领域的服务开放,User 作为独立的聚合根,其数据操作的业务规则(比如邮箱格式校验、密码加密逻辑、账号状态校验等)全部封装在 User Service 内部,其他领域直接调用非本领域的 Repository 会破坏封装性,导致业务规则散落在多个服务中,后续迭代维护极易出现逻辑不一致的问题。
- 避免遗漏关联逻辑:User 数据更新通常会附带通用的附属操作,比如修改邮箱后触发校验邮件发送、更新用户基础信息缓存、触发用户信息变更的领域事件等,这些逻辑全部内置在 User Service 中,直接调用 User Repository 会全部遗漏这些步骤,引发数据一致性问题。
- 事务控制更灵活:如果两个更新操作需要保证原子性,你可以在 Customer Service 的更新方法外层加事务注解,先调用 User Service 完成用户基础信息更新,再调用 Customer Repository 完成客户资料更新,同一个事务上下文内可以保证两个操作要么全部成功要么全部回滚,不会出现数据不一致。
特殊情况说明
如果你的架构中将 User 和 Customer Profile 划为同一个聚合,User 是该聚合的根节点,Customer Profile 是聚合内的附属实体,那你可以直接在 Customer Service 中操作 User 聚合根的所有属性,最后统一通过 User Repository 保存整个聚合即可。但按照你给出的表结构,User 是客户、教练等不同角色共用的基础表,属于独立的聚合根,所以必须走服务层调用。
内容的提问来源于stack exchange,提问作者hattom
相关产品推荐
相关产品推荐

