首页/开发/代码质量与评审速查/分层与依赖方向(同心圆模型)
设计原则与模式62 条

分层与依赖方向(同心圆模型)

分层架构约束依赖方向:外层可依赖内层,内层不感知外层(Clean Architecture 同心圆:实体 → 用例 → 接口适配器 → 框架与驱动);依赖穿过边界时由内层定义接口。

分层与依赖方向是什么

分层架构的核心不是目录结构,而是依赖方向:外层可以依赖内层,内层不感知外层。Clean Architecture 把它画成同心圆——实体在中心,往外依次是用例、接口适配器、框架与驱动。依赖需要穿过边界反向指回内层时,由内层定义接口、外层提供实现,这就是依赖倒置在分层里的用法。

基本信息

方向外向内依赖,内对外无感
边界依赖倒置跨越:端口定义在内、实现在外
检验核心模块的 import 里不出现框架与存储类型
相关模型六边形架构、端口与适配器、整洁架构

落地要点

  • 内层只依赖语言标准库与自己的抽象,不依赖 Web 框架或 ORM
  • 持久化、消息、外部 API 的接口由内层定义,实现在外层
  • 领域对象不应直接抛出框架专属异常,细节从内向外泄漏
  • 跨层调用要有明确理由,临时直连应标注为待偿还项
  • 用构建期检查固化依赖规则,让它不依赖人的自觉
  • 数据模型分界要清晰:DTO 与领域对象分开,避免一层改字段层层改

分层示例

分层示例
entity  ←  usecase  ←  adapter  ←  framework

// 用例层定义端口(依赖倒置的关键)
interface UserRepo { Optional<User> findById(UserId id); }

// 基础设施层实现端口(外圈)
class JpaUserRepo implements UserRepo { /* JPA 细节在此 */ }

// 用例层只认接口
class RegisterUser {
    private final UserRepo repo;
    void handle(Cmd cmd) { repo.save(User.create(cmd)); }
}

各层职责

层职责不该出现的东西
实体业务不变量与规则持久化注解、HTTP 类型
用例编排流程、事务边界声明SQL、框架配置
适配器协议转换、调用转发业务规则
框架与驱动I/O、序列化、外部集成领域决策
分层最常见的失败是只落在目录名上:包结构好看,但用例层直接 import 了持久化实现,规则形同虚设。可行的检验方式是在 CI 里跑依赖检查,让违规的代码合不进去。
分层数量不是目的:一个小型服务里实体层与用例层合并完全合理。判断依据是「这一层是否承担了独立的、可能独立变化的责任」,而不是别人家的架构图有几层。

易错点

  • 分层只落在目录名:跨层直接 import,规则形同虚设,改动依旧联动
  • 核心层直接抛框架异常:细节从内向外泄漏,换框架等于重写业务
  • 为分层而分层:一次查询穿过四层却没有任何一层增加价值,维护成本翻倍
  • 依赖规则不落工具:靠评审记忆维持,人手一变约定就失效

数据来源与参考

  • Robert C. Martin《Clean Architecture》同心圆模型;Alistair Cockburn 六边形架构
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌