根据领域驱动设计(DDD)和清晁架构(Clean Architecture)的思想,以下是一个推荐的目录结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| project/ ├── api/ # API 定义层 │ ├── proto/ # Protocol Buffers 定义 │ └── openapi/ # REST API 定义 ├── cmd/ # 应用程序入口 │ └── server/ ├── internal/ # 私有应用程序代码 │ ├── domain/ # 领域模型层 │ │ ├── entity/ # 实体定义 │ │ ├── valueobject/ # 值对象 │ │ └── repository/ # 仓储接口 │ ├── infrastructure/ # 基础设施层 │ │ ├── persistence/ # 数据持久化实现 │ │ ├── messaging/ # 消息队列实现 │ │ └── cache/ # 缓存实现 │ ├── application/ # 应用服务层 │ │ ├── service/ # 应用服务 │ │ ├── dto/ # 数据传输对象 │ │ └── assembler/ # DTO 转换器 │ └── interfaces/ # 接口层 │ ├── http/ # HTTP 处理器 │ ├── grpc/ # gRPC 处理器 │ └── event/ # 事件处理器 ├── pkg/ # 公共代码包 │ ├── logger/ # 日志工具 │ ├── errors/ # 错误处理 │ └── middleware/ # 中间件 └── configs/ # 配置文件
|
- 领域层 (Domain Layer)
- 位于架构的最核心层
- 包含业务实体和核心业务规则
- 不依赖于其他层
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| package entity
type Order struct { ID string CustomerID string Status OrderStatus Items []OrderItem CreatedAt time.Time }
func (o *Order) CalculateTotal() decimal.Decimal { }
|
- 应用层 (Application Layer)
- 编排领域对象来执行特定的应用程序任务
- 实现事务边界
- 不包含业务规则,只负责流程编排
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| package service
type OrderService struct { orderRepo repository.OrderRepository eventPub event.Publisher txManager transaction.Manager }
func (s *OrderService) CreateOrder(ctx context.Context, dto dto.CreateOrderDTO) (*dto.OrderDTO, error) { return s.txManager.RunInTransaction(ctx, func(ctx context.Context) error { }) }
|
- 接口层 (Interface Layer)
- 处理外部请求
- 请求验证和响应格式化
- 错误处理和日志记录
1 2 3 4 5 6 7 8 9 10 11
| package handler
type OrderHandler struct { orderService application.OrderService logger *logger.Logger }
func (h *OrderHandler) CreateOrder(c *gin.Context) { }
|
- 基础设施层 (Infrastructure Layer)
- 提供技术能力的实现
- 实现领域层定义的接口
- 包含数据库访问、消息队列、缓存等
1 2 3 4 5 6 7 8 9 10
| package mysql
type OrderRepository struct { db *gorm.DB }
func (r *OrderRepository) Save(ctx context.Context, order *entity.Order) error { }
|
- 公共层 (Common/Pkg Layer)
1 2 3 4 5 6 7
| package errors
type BusinessError struct { Code string Message string }
|
关键设计原则:
- 依赖倒置原则
- 高层模块不应该依赖低层模块,应该依赖于抽象
- 在领域层定义接口,在基础设施层实现
- 关注点分离
- 每一层都有明确的职责
- 避免跨层调用,保持层次间的清晰边界
- 依赖注入
1 2 3 4 5 6 7 8 9 10
| func InitializeServer() *Server { wire.Build( mysql.NewOrderRepository, service.NewOrderService, handler.NewOrderHandler, ) return nil }
|
- 错误处理
- 定义清晰的错误类型和处理流程
- 在适当的层处理或转换错误
- 事务管理
- 配置管理
这种分层架构的优势:
- 可维护性:每层职责清晰,易于理解和维护
- 可测试性:各层可以独立测试,易于模拟依赖
- 可扩展性:新功能可以在不影响其他层的情况下添加
- 解耦性:层间通过接口通信,降低耦合度