Post
清洁架构四层分层与依赖反转原理
清洁架构:以业务为核心的分层设计原则
概述
清洁架构(Clean Architecture)是一种以业务逻辑为核心、强调解耦与可维护性的软件架构模式。其核心目标是将业务规则与技术实现(如数据库、UI框架)分离,通过分层结构和依赖反转原则,实现系统的可测试性、可扩展性与长期维护性。
核心概念
清洁架构通过四层分层结构实现业务逻辑与技术细节的解耦,各层从内到外依次为:
| 层级 | 名称 | 作用 |
|---|---|---|
| 1 | Entities | 领域模型与业务规则,包含纯粹的业务逻辑,不依赖任何技术实现。 |
| 2 | Use Cases | 应用用例/业务流程,调用 Entities 完成任务,定义系统的行为逻辑。 |
| 3 | Interface Adapters | 接口适配层,负责数据转换(如 HTTP 请求解析、数据库查询结果映射)。 |
| 4 | Frameworks & Drivers | 技术实现层,包含 Web 框架、数据库、UI、第三方库等具体技术细节。 |
依赖方向:外层(如 Frameworks & Drivers)可以依赖内层(如 Entities),但内层不能依赖外层。通过接口反转(Dependency Inversion)实现解耦,确保技术细节的变化不会影响核心业务逻辑。
工作原理
清洁架构的核心在于依赖反转与分层隔离:
-
依赖方向:
- 外层(技术实现)通过接口依赖内层(业务逻辑),而非直接引用具体实现。
- 例如:HTTP 控制器(Interface Adapters)通过接口调用 Use Cases,而非直接操作数据库(Frameworks & Drivers)。
-
接口连接各层:
- 各层通过定义清晰的接口进行通信,例如:
- Use Cases 提供接口供 Interface Adapters 调用。
- Infrastructure 层(如数据库驱动)实现 Interface Adapters 的接口。
- 各层通过定义清晰的接口进行通信,例如:
-
解耦技术细节:
- 业务逻辑(Entities/Use Cases)独立于具体技术(如数据库类型、Web 框架),便于替换或升级技术栈。
使用方法
项目结构示例
典型的 Go 项目结构可能如下:
application/
├── cmd/ # 入口程序(如 main.go)
├── internal/ # 核心业务逻辑
│ ├── domain/ # Entities:领域模型和接口(如 model.go)
│ ├── usecase/ # Use Cases:应用逻辑(如 user.go)
│ ├── adapter/ # Interface Adapters:HTTP 控制器、gRPC 服务等
│ │ ├── db/ # 数据库实现(如 MySQL/PostgreSQL)
│ │ ├── web/ # Web 框架适配(如 Gin、Echo)
│ ├── layer/ # Infrastructure:技术细节实现
│ │ ├── controller/ # HTTP 接口适配
│ │ ├── repository/ # 数据库接口(如 repo/postgres.go)
├── pkg/ # 工具函数/共用库
目录命名建议
为避免与标准库冲突或提升可读性,建议:
delivery/http→ 改为delivery/web或delivery/rest(避免与net/http冲突)。repository→ 可细化为repo/postgres或repo/mysql(明确技术实现)。
注意事项
-
依赖方向严格遵循:
- 内层(Entities/Use Cases)不能依赖外层(Frameworks & Drivers)。
- 例如:Use Cases 中不应直接调用
gorm或sql.DB,而应通过接口定义数据库操作。
-
测试友好性:
- 通过接口解耦,可轻松用 Mock 对象替换真实依赖(如用内存数据库替代 MySQL),提升单元测试效率。
-
技术栈灵活性:
- 业务逻辑层独立于具体技术,可灵活切换框架(如从 Gin 切换到 FastHTTP)或数据库(如从 PostgreSQL 切换到 MongoDB)。
-
目录结构清晰化:
- 避免
entity/domain与usecase混淆,保持entity与domain一致(若领域模型与实体分离)。
- 避免
总结
清洁架构通过分层与依赖反转,将业务逻辑与技术细节解耦,显著提升系统的可维护性与可测试性。其核心价值在于:业务规则应独立于技术实现,技术细节的变化不应影响核心逻辑。在实际开发中,需严格遵循依赖方向,合理设计接口,并通过清晰的目录结构降低耦合度。