在 DDD 分层架构中,应用层是否仅用于处理对外暴露的接口?
对于不对外提供接口的场景,例如通过第三方接口获取 K 线数据并持久化到数据库,这类逻辑应当归属于哪一层?
这是个很典型的 DDD 分层架构中常见的困惑
在 DDD 分层架构(通常是四层:UI/接口层、应用层、领域层、基础设施层)里,各层的职责大概是这样:
- 接口层 (Interface / API / UI):对外提供访问入口,比如 HTTP API、RPC、CLI。
- 应用层 (Application):编排业务用例,定义系统行为的流程,调用领域对象或服务。它本身不实现业务规则,只是协调。
- 领域层 (Domain):业务核心逻辑和规则,实体、值对象、领域服务、聚合根。
- 基础设施层 (Infrastructure):技术实现,比如数据库访问、第三方服务调用、消息队列等。
回答
应用层是否仅用于处理对外暴露的接口?
不是。
应用层并不是“只为对外接口存在”,它的核心作用是编排用例。任何系统行为——无论是 对外 API 请求触发,还是 内部定时任务、消费消息、调用第三方接口——都应该通过应用层来发起和组织。
举个例子(获取 K 线并保存数据库)
比如你有个需求:
「定时任务调用第三方行情接口 → 获取 K 线数据 → 存到数据库」。
在 DDD 分层里可以这样放:
触发点(可能是定时任务 scheduler、消息队列 consumer)——放在接口层(Infrastructure 提供调度,但调用 Application)。
应用层 (Application Service):定义一个用例,比如
FetchKlineAppService.FetchAndStoreKlines()
。它负责:- 调用领域服务/基础设施服务去抓取数据
- 调用领域逻辑做转换、校验
- 调用仓储保存聚合根
领域层 (Domain):
- 定义
Kline
聚合(时间、开高低收、成交量等) - 定义必要的业务规则(例如校验数据完整性)
- 定义
基础设施层 (Infrastructure):
- 实现第三方行情接口的调用(比如
KlineMarketAPIAdapter
) - 实现仓储(
KlineRepository
,对数据库的持久化)
- 实现第三方行情接口的调用(比如
为什么要这样分?
- 如果你把逻辑直接放到 Infrastructure(比如写个 job 调第三方接口然后 insert DB),那应用层就被绕过了,业务流程散落在各处,后续难以维护。
- 应用层的价值就是 统一编排和对齐用例,所以即便不是对外 API,也应该通过应用层来调用。
✅ 总结
应用层不是只给“对外接口”用的,而是所有业务用例(对外/内部)都要经过它来编排。
获取第三方 K 线再存库的逻辑:
- 定时任务(接口层触发)
- 应用层协调
- 领域层定义数据和规则
- 基础设施实现外部 API 调用和持久化