Files
Inbox/Go项目实战/00_顶层设计/关于项目的顶层设计模式和风格.md
2025-12-11 07:24:36 +08:00

131 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
tags: []
aliases:
- 🏗️ Project Architecture & Design Guidelines (v1.0)
date created: 星期日, 十二月 7日 2025, 11:57:43 中午
date modified: 星期二, 十二月 9日 2025, 11:00:14 晚上
---
# 🏗️ Project Architecture & Design Guidelines (v1.0)
项目代号: Enterprise-CMS-Core
架构风格: 模块化整洁架构 (Modular Clean Architecture)
核心原则: 实用主义 (Pragmatic)、Go 原生思维 (Idiomatic)、领域驱动 (DDD-Lite)
## 1. 技术栈约束 (Tech Stack Constraints)
- **Language:** Go 1.21+
- **Web Framework:** Gin
- **Database:** PostgreSQL (Primary), Redis (Cache)
- **ORM:** GORM (With Migration Tools)
- **Dependency Injection:** Google Wire
- **Configuration:** Viper (YAML)
- **Observability:** Zap (Log), Prometheus (Metrics), Jaeger (Trace)
- **Documentation:** Swagger / OpenAPI 3.0
---
## 2. 目录结构规范 (Directory Structure)
采用 **“按领域分包 (Package by Domain)”** 的扁平化结构,而非传统的按层分包。
```Plaintext
root/
├── cmd/server/
│ ├── main.go # 仅包含 wire 初始化与 app.Run()
│ └── wire.go # 顶层依赖注入定义
├── config/ # 配置文件模板 (config.yaml)
├── internal/
│ ├── api/ # [API层] 全局通用的 HTTP DTO (Request/Response)
│ ├── middleware/ # [中间件] Gin 中间件 (Auth, CORS, Logger)
│ ├── pkg/ # [基础设施] 内部通用组件 (AppResult, ErrorCode)
│ │
│ │ # --- 核心业务领域 (Domain Modules) ---
│ │ # 每个领域包内部扁平化,自包含所有逻辑
│ ├── user/ # [示例] 用户领域
│ │ ├── entity.go # 核心实体 (GORM Model)
│ │ ├── repository.go # 仓储接口定义 + GORM 实现
│ │ ├── service.go # 业务逻辑 (Service Struct)
│ │ ├── handler.go # HTTP 控制器 (Controller)
│ │ └── provider.go # Wire ProviderSet
│ │
│ └── article/ # [示例] 文章领域 (结构同上)
├── pkg/ # [外部库] 可抽离的通用工具 (Hash, JWT, Logger封装)
├── migrations/ # 数据库迁移 SQL 文件 (up/down)
├── go.mod
└── Makefile
```
---
## 3. 核心架构设计规则 (Architectural Rules)
### 3.1. 依赖倒置与注入 (IoC & DI)
- **规则:** 严禁在业务代码中手动 `New()` 依赖对象。
- **实现:** 所有依赖关系必须通过 `NewStruct(dep Interface)` 构造函数声明,并由 `Google Wire` 在编译期自动组装。
- **模块化注入:** 每个领域包(如 `internal/user`)必须包含一个 `provider.go`,导出 `var ProviderSet = wire.NewSet(…)`,供顶层 `cmd/server/wire.go` 聚合。
### 3.2. 接口策略 (Interface Strategy)
- **Repository (必须):** 仓储层**必须**定义接口(例如 `UserRepository`),以支持 Mock 测试和数据库切换。
- **Service (按需):** 默认**不需要**定义 Service 接口,直接使用 Struct。仅在以下情况提取接口
1. 出现循环依赖。
2. 需要对 Service 进行 Mock 测试。
3. 该 Service 存在多种策略实现(如 `PaymentService` 有支付宝/微信两种实现)。
### 3.3. 领域包扁平化 (Flat Domain Package)
- **规则:** 在 `internal/user/` 等领域包内,**不再**建立 `service/`, `repo/` 子目录。
- **原因:** 利用 Go 的 `package` 级私有可见性,隐藏领域内部细节(如辅助函数、内部 DTO仅暴露必要的 Handler 和 Service 方法。
### 3.4. 数据模型 (Model Vs Entity)
- **策略:** 采用 **"Pragmatic Entity"** 模式。
- **定义:** `entity.go` 中的结构体既是业务实体,也是 GORM 模型(带 `gorm:"…"` 标签)。
- **例外:** 只有当数据库存储结构与业务逻辑结构差异巨大时,才在 Repository 内部引入独立的 PO (Persistent Object) 并进行转换。
---
## 4. 编码实施标准 (Implementation Standards)
### 4.1. 错误处理 (Error Handling)
- **禁止:** 严禁直接返回 `error` 字符串给前端。
- **必须:** Service 层返回标准 `error`Controller 层通过 `pkg/app` 将其转换为统一响应格式。
- **格式:**
```Go
// Response JSON
{
"code": 20001,
"msg": "User already exists",
"data": null
}
```
### 4.2. 数据库交互 (Database Interaction)
- **禁止:** Controller 层严禁导入 `gorm` 包,严禁执行 SQL。
- **迁移:** 生产环境严禁使用 `AutoMigrate`。必须使用 `migrations/` 目录下的版本化 SQL 脚本进行变更。
### 4.3. 路由注册 (Router Registration)
- **规则:** 路由不再集中管理。
- **实现:** 每个领域包暴露一个 `RegisterRoutes(r *gin.RouterGroup)` 方法。在 `main.go` 启动时,统一调用各模块的注册方法。
---
## 5. AI 编程指令 (Instruction for AI Agent)
> **当作为 AI 助手编写代码时,请严格遵守以下指令:**
1. **Context Check:** 在生成代码前,检查当前目录结构是否符合 `Section 2`。如果不符,请优先建议重构或遵循现有结构。
2. **No Logic Leak:** 确保 HTTP 处理逻辑(解析参数、校验参数)留在 `handler.go`,业务规则(判断权限、计算)留在 `service.go`SQL 操作留在 `repository.go`。
3. **Wire Awareness:** 每当新增 Service 或 Repository必须自动更新同目录下的 `provider.go`,并在 `cmd/server/wire.go` 中检查是否需要重新生成。
4. **Testability:** 编写 Repository 代码时,优先考虑“如何 Mock”。