You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DDD与整洁架构下placeOrder调用远程API的层级选型问题

问题解答

首先给出明确结论:
远程调用的具体实现绝对不能放在领域层,但你提到的「在领域层定义依赖服务的抽象接口、通过依赖注入接入外层实现」的思路完全符合DDD和整洁架构的设计原则,反倒是不建议把所有远程API调用逻辑全堆在应用层。

具体落地规则

  • 先守住分层依赖的核心规则:领域层是系统最核心的内层,只承载业务规则,不能感知任何外部技术实现细节——不管你是调微服务、读缓存、查本地数据库还是调第三方接口,这些技术细节的实现全要放在外层(基础设施层/应用层的适配模块),依赖方向只能是外层指向内层。
  • 领域层的接口定义要完全剥离技术语义:不要在领域层定义类似IProductServiceClient这种一看就是RPC调用的接口,要按领域概念命名,比如IProductLookupService、IUserAddressRepository,接口方法只返回领域模型对象,比如SkuInfo GetSku(SkuId skuId)、DeliveryAddress GetUserAddress(UserId userId, AddressId addressId),接口定义里完全不体现数据来源。
  • 不要把前置数据拉取全堆在应用层:很多初学者做分层的时候容易走偏,在应用层把商品详情、用户地址全通过远程调用查完,攒成一堆参数传给领域层的placeOrder方法,这本质是领域逻辑泄露——「下单必须校验商品存在且可售、地址属于当前用户」这类规则本来是核心业务逻辑,全散在应用层的流程代码里,后续改规则很容易出现逻辑遗漏。正确的流程是:应用层只接收最原始的下单请求参数(用户ID、选中的Sku ID列表、地址ID),直接调用领域服务的placeOrder方法;领域服务在执行业务规则的过程中,通过自己定义的抽象接口获取需要的商品、地址数据,完成校验、价格计算、订单实体构建全流程,根本不需要关心这些数据是远程拉取的还是本地读取的。
  • 外层实现只做适配:你写的商品微服务调用逻辑、用户档案服务调用逻辑、对应的序列化、异常处理、熔断降级逻辑,全放在外层的适配模块里,实现领域层定义的抽象接口,项目启动时通过依赖注入把实现实例注入给领域服务即可,完全符合依赖倒置原则。

常见误区提醒

判断逻辑该放哪的标准非常简单:如果一段规则是不管你用什么技术栈、什么部署架构都不会变的业务规则(比如下单必须有可售商品、必须有有效收货地址),那相关的逻辑控制就应该留在领域层;如果是和具体技术实现绑定的逻辑(比如用HTTP还是Dubbo调远程服务、超时时间设多少、失败了重试几次),就放在外层实现。

不要为了追求所谓的「领域层绝对纯净」,把领域服务需要主动控制的依赖获取逻辑全赶到应用层,最后把应用层写成臃肿的事务脚本,领域层只剩纯get/set的贫血模型,完全违背DDD的设计初衷。

内容的提问来源于stack exchange,提问作者tarek salem

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 10:06:20