用途
分层架构把系统组织成若干水平层,典型为:表现层(Presentation)→ 业务层(Business)→ 持久层(Persistence)→ 数据库(Database)。依赖严格向下流动,上层依赖下层,下层绝不反向依赖上层。
何时使用
- 简单单体,且 UI、业务逻辑与数据分离清晰。
- 团队首次搭建服务端架构——分层是最容易理解的心智模型。
- 系统主要的变化轴是“替换 UI”或“替换数据库”(在合理范围内)。
- 受监管、团队规模或部署等约束,使微服务或事件驱动显得过度设计的场景。
何时不使用
- 领域模型足够丰富,业务层成为瓶颈并应驱动其他所有层时——考虑 arch-hexagonal(依赖方向反转,让领域处于中心)。
- 系统确实需要按业务能力独立扩展、部署或数据归属——参见 arch-microservices。
- 主要通信模式是异步、事件形态的——参见 arch-event-driven。
核心内容
经典四层(存在变体):
- 表现层(Presentation)——UI、API 控制器、命令行处理器。
- 业务层(Business)——领域逻辑、用例、服务。
- 持久层(Persistence)——仓储、ORM、数据访问。
- 数据库(Database)——物理存储。
依赖规则:每一层可以调用紧邻其下的层。跳过一层,有些团队允许(开放层),有些团队禁止(封闭层)。约定应显式并形成文档。
开放层与封闭层:封闭层强制每次调用都经过下一层——清晰但冗长。开放层允许在某层无价值时被绕过(例如两个真实层之间的薄“共享工具”层)。选定一种约定,不要混用。
为什么它是默认选择:分层架构易教、易上手、对 CRUD 形态系统易推理。除非有明确理由选择其他方案,否则它是合适的起点。
它在何处失效:当业务层开始依赖持久层的类型(例如领域实体本身就是 JPA @Entity),抽象已经倒置——数据库尾巴在摇领域狗。此时应考察 arch-hexagonal。
决策准则
- 任何新单体都从分层开始。无聊的选择本身就是优点。
- 默认使用封闭层;只有当绕过某层确实更干净时,才把该层提升为“开放”。
- 业务层禁止从表现层导入。在 CI 中检测违规(参见 arch-fitness-functions)。
- 如果业务层持续需要基础设施类型(数据库连接、HTTP 客户端),说明架构在要求翻转——考虑六边形。
反模式
- 沉洞反模式(Sinkhole anti-pattern):某层只把调用透传给下层而不做任何转换。意味着:(1) 该层不该存在,或 (2) 该层应开放。常见于过度设计的“服务”层。
- 泄漏层(Leaky layer):下层类型(JPA 实体、HTTP DTO)出现在上层。使上层耦合于下层的实现。
- 双向依赖:下层向上调用上层——通常通过回调或循环导入。破坏分层。
- 没有架构的分层:因为目录命名为 presentation/、business/、persistence/ 就称其为“分层”,但没有强制的依赖方向。命名表演。
参见
- arch-hexagonal——当领域应处于中心而非某一层时。
- arch-fitness-functions——在 CI 中强制层边界。
- ddd-anti-patterns——贫血领域模型是业务逻辑漏入表现层/持久层的信号。
参考资料
- Richards & Ford, Fundamentals of Software Architecture, Ch. 10(Layered Architecture Style)。
- Buschmann et al., Pattern-Oriented Software Architecture, Vol. 1——分层模式原始参考。