为什么千万别把“业务服务接口”放进 Abstractions 层?
DDD 分层的底层逻辑告诉你真相
在企业级项目里,尤其是 青岛软件开发 和企业数字化系统构建中,我见过太多团队把 业务服务接口(Service Interfaces) 随手丢进 Abstractions 层。
原因通常很简单:
“好共享、好引用,不就完了吗?”
然而,这种做法看似方便,实则是 对 DDD 分层原则的严重误解。
长期会带来 依赖方向混乱、抽象层膨胀、业务边界模糊 等一系列问题。
今天我们就把这件事一次讲清。
🚫 Abstractions 层到底应该放什么?(重点!)
很多项目的问题,就是把 Abstractions 当成“万能垃圾桶”。
正确的 Abstractions 层,只应该放技术相关的基础抽象:
- ✔
Result<T>/Error等基础响应模型 - ✔ 技术工具契约,如
IClock、ISerializer - ✔ 第三方依赖的抽象,如缓存接口、消息队列接口
- ✔ 全局通用的基础类型
绝对不应该放:
- ❌ 业务服务接口
- ❌ 业务模型
- ❌ 任何属于业务逻辑的东西
因为:
Abstractions 关注技术,不关注业务。
🧩 那业务服务接口应该放在哪里?
业务接口只可能属于两类:
✔ 1)属于业务规则的接口 → 放 Domain 层
当接口表达“业务知识”,它就应该属于领域层。
例如:
- 运价计算服务
- 模板解析规则
- 订单规则校验服务
- 商品库存领域逻辑
这些都是“业务本体”,自然属于 Domain。
✔ 2)属于流程编排的接口 → 放 Application 层
当接口描述“应用流程”,就属于应用服务。
例如:
- 同步模板数据流程
- 创建订单流程
- 支付流程编排
- 调用领域服务 + 调用基础设施的组合逻辑
这些都是“用例级别”的逻辑,应放 Application。
🧨 为什么不能把业务接口丢进 Abstractions?
因为这样会导致:
- ❌ 层间依赖混乱
- ❌ 所有层都能访问业务接口 → 业务泄漏
- ❌ 抽象层无限膨胀 → 成为垃圾桶
- ❌ 业务边界模糊,难以扩展
- ❌ 新人根本不知道业务属于哪层
尤其在 青岛软件开发项目交付 中,多团队协作时,这种混乱会被无限放大。
🧱 正确的四层结构示例(推荐实践)
/Domain
- Entities
- ValueObjects
- DomainServices (接口与实现)
- Aggregates
/Application
- ApplicationServices (接口与实现)
- DTOs
- Commands / Queries
/Abstractions
- Result<T>
- Errors
- ICacheService
- IEventPublisher
- IClock
/Infrastructure
- RedisCacheService
- EfRepository
- EventPublisher只需记住一句话:
业务归业务,抽象归抽象。
你就不会走错。
🎯 总结
很多同学把业务接口放进 Abstractions,看似方便,实则违背 DDD 分层原则。
记住三点:
- 🔹 Abstractions 是技术抽象层,不是业务抽象层
- 🔹 领域接口 → Domain;流程接口 → Application
- 🔹 分层越干净,系统越稳定、越可维护
如果你正在做 青岛软件开发、企业官网系统、行业 SaaS 架构,一定要避免这个常见错误。
最后更新于