forked from datawhale/whale-town-end
docs:添加架构重构文档
- 新增 ARCHITECTURE_REFACTORING.md 文档 - 记录项目架构重构计划和进度
This commit is contained in:
295
docs/ARCHITECTURE_REFACTORING.md
Normal file
295
docs/ARCHITECTURE_REFACTORING.md
Normal file
@@ -0,0 +1,295 @@
|
||||
# 架构重构文档
|
||||
|
||||
## 重构目标
|
||||
|
||||
将现有的混合架构重构为清晰的4层架构,实现更好的关注点分离和代码组织。
|
||||
|
||||
## 架构对比
|
||||
|
||||
### 重构前
|
||||
|
||||
```
|
||||
src/
|
||||
├── business/auth/ # 混合了Gateway和Business职责
|
||||
│ ├── login.controller.ts # HTTP协议处理
|
||||
│ ├── login.service.ts # 业务逻辑
|
||||
│ ├── jwt_auth.guard.ts # 认证守卫
|
||||
│ └── dto/ # 数据传输对象
|
||||
└── core/login_core/ # 核心层
|
||||
└── login_core.service.ts # 数据访问和基础设施
|
||||
```
|
||||
|
||||
### 重构后
|
||||
|
||||
```
|
||||
src/
|
||||
├── gateway/auth/ # 网关层(新增)
|
||||
│ ├── login.controller.ts # HTTP协议处理
|
||||
│ ├── register.controller.ts # HTTP协议处理
|
||||
│ ├── jwt_auth.guard.ts # 认证守卫
|
||||
│ ├── dto/ # 数据传输对象
|
||||
│ └── auth.gateway.module.ts # 网关模块
|
||||
├── business/auth/ # 业务层(精简)
|
||||
│ ├── login.service.ts # 登录业务逻辑
|
||||
│ ├── register.service.ts # 注册业务逻辑
|
||||
│ └── auth.module.ts # 业务模块
|
||||
└── core/login_core/ # 核心层(不变)
|
||||
└── login_core.service.ts # 数据访问和基础设施
|
||||
```
|
||||
|
||||
## 4层架构说明
|
||||
|
||||
### 1. Transport Layer(传输层)- 可选
|
||||
|
||||
**位置**:`src/transport/`
|
||||
|
||||
**职责**:
|
||||
- 底层网络通信和连接管理
|
||||
- WebSocket服务器、TCP/UDP服务器
|
||||
- 原生Socket连接池管理
|
||||
|
||||
**说明**:对于HTTP应用,NestJS已经提供了传输层,无需额外实现。对于WebSocket等特殊协议,可以在此层实现。
|
||||
|
||||
### 2. Gateway Layer(网关层)
|
||||
|
||||
**位置**:`src/gateway/`
|
||||
|
||||
**职责**:
|
||||
- HTTP协议处理和请求响应
|
||||
- 数据验证(DTO)
|
||||
- 路由管理
|
||||
- 认证守卫
|
||||
- 错误转换(业务错误 → HTTP状态码)
|
||||
- API文档
|
||||
|
||||
**原则**:
|
||||
- ✅ 只做协议转换,不做业务逻辑
|
||||
- ✅ 使用DTO进行数据验证
|
||||
- ✅ 统一的错误处理
|
||||
- ❌ 不直接访问数据库
|
||||
- ❌ 不包含业务规则
|
||||
|
||||
**示例**:
|
||||
```typescript
|
||||
@Controller('auth')
|
||||
export class LoginController {
|
||||
constructor(private readonly loginService: LoginService) {}
|
||||
|
||||
@Post('login')
|
||||
async login(@Body() loginDto: LoginDto, @Res() res: Response): Promise<void> {
|
||||
// 只做协议转换
|
||||
const result = await this.loginService.login({
|
||||
identifier: loginDto.identifier,
|
||||
password: loginDto.password
|
||||
});
|
||||
|
||||
// 转换为HTTP响应
|
||||
this.handleResponse(result, res);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Business Layer(业务层)
|
||||
|
||||
**位置**:`src/business/`
|
||||
|
||||
**职责**:
|
||||
- 业务逻辑实现
|
||||
- 业务流程控制
|
||||
- 服务协调
|
||||
- 业务规则验证
|
||||
- 事务管理
|
||||
|
||||
**原则**:
|
||||
- ✅ 实现所有业务逻辑
|
||||
- ✅ 协调多个Core层服务
|
||||
- ✅ 返回统一的业务响应
|
||||
- ❌ 不处理HTTP协议
|
||||
- ❌ 不直接访问数据库
|
||||
|
||||
**示例**:
|
||||
```typescript
|
||||
@Injectable()
|
||||
export class LoginService {
|
||||
async login(loginRequest: LoginRequest): Promise<ApiResponse<LoginResponse>> {
|
||||
try {
|
||||
// 1. 调用核心服务进行认证
|
||||
const authResult = await this.loginCoreService.login(loginRequest);
|
||||
|
||||
// 2. 业务逻辑:验证Zulip账号
|
||||
await this.validateAndUpdateZulipApiKey(authResult.user);
|
||||
|
||||
// 3. 生成JWT令牌
|
||||
const tokenPair = await this.loginCoreService.generateTokenPair(authResult.user);
|
||||
|
||||
// 4. 返回业务响应
|
||||
return {
|
||||
success: true,
|
||||
data: { user: this.formatUserInfo(authResult.user), ...tokenPair },
|
||||
message: '登录成功'
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
success: false,
|
||||
message: error.message,
|
||||
error_code: 'LOGIN_FAILED'
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Core Layer(核心层)
|
||||
|
||||
**位置**:`src/core/`
|
||||
|
||||
**职责**:
|
||||
- 数据访问(数据库、缓存)
|
||||
- 基础设施(Redis、消息队列)
|
||||
- 外部系统集成
|
||||
- 技术实现细节
|
||||
|
||||
**原则**:
|
||||
- ✅ 提供技术基础设施
|
||||
- ✅ 数据持久化和缓存
|
||||
- ✅ 外部API集成
|
||||
- ❌ 不包含业务逻辑
|
||||
- ❌ 不处理HTTP协议
|
||||
|
||||
## 数据流向
|
||||
|
||||
```
|
||||
客户端请求
|
||||
↓
|
||||
Gateway Layer (Controller)
|
||||
↓ 调用
|
||||
Business Layer (Service)
|
||||
↓ 调用
|
||||
Core Layer (Data Access)
|
||||
↓
|
||||
数据库/缓存/外部API
|
||||
```
|
||||
|
||||
## 依赖关系
|
||||
|
||||
```
|
||||
Gateway → Business → Core
|
||||
```
|
||||
|
||||
- Gateway层依赖Business层
|
||||
- Business层依赖Core层
|
||||
- Core层不依赖任何业务层
|
||||
- 依赖方向单向,不允许反向依赖
|
||||
|
||||
## 重构步骤
|
||||
|
||||
### 第一阶段:登录注册模块(已完成)
|
||||
|
||||
1. ✅ 创建`src/gateway/auth/`目录
|
||||
2. ✅ 移动Controller到Gateway层
|
||||
3. ✅ 移动DTO到Gateway层
|
||||
4. ✅ 移动Guard到Gateway层
|
||||
5. ✅ 创建`AuthGatewayModule`
|
||||
6. ✅ 更新Business层模块,移除Controller
|
||||
7. ✅ 更新`app.module.ts`使用新的Gateway模块
|
||||
8. ✅ 创建架构文档
|
||||
|
||||
### 第二阶段:其他业务模块(待进行)
|
||||
|
||||
- [ ] 重构`location_broadcast`模块
|
||||
- [ ] 重构`user_mgmt`模块
|
||||
- [ ] 重构`admin`模块
|
||||
- [ ] 重构`zulip`模块
|
||||
- [ ] 重构`notice`模块
|
||||
|
||||
### 第三阶段:WebSocket模块(待进行)
|
||||
|
||||
- [ ] 创建`src/transport/websocket/`
|
||||
- [ ] 实现原生WebSocket服务器
|
||||
- [ ] 创建`src/gateway/location-broadcast/`
|
||||
- [ ] 移动WebSocket Gateway到Gateway层
|
||||
|
||||
## 迁移指南
|
||||
|
||||
### 如何判断代码应该放在哪一层?
|
||||
|
||||
**Gateway层**:
|
||||
- 包含`@Controller()`装饰器
|
||||
- 包含`@Get()`, `@Post()`等HTTP方法装饰器
|
||||
- 包含`@Body()`, `@Param()`, `@Query()`等参数装饰器
|
||||
- 包含DTO类(`class LoginDto`)
|
||||
- 包含Guard类(`class JwtAuthGuard`)
|
||||
|
||||
**Business层**:
|
||||
- 包含`@Injectable()`装饰器
|
||||
- 包含业务逻辑方法
|
||||
- 协调多个服务
|
||||
- 返回`ApiResponse<T>`格式的响应
|
||||
|
||||
**Core层**:
|
||||
- 包含数据库访问代码
|
||||
- 包含Redis操作代码
|
||||
- 包含外部API调用
|
||||
- 包含技术实现细节
|
||||
|
||||
### 重构Checklist
|
||||
|
||||
对于每个模块:
|
||||
|
||||
1. [ ] 识别Controller文件
|
||||
2. [ ] 创建对应的Gateway目录
|
||||
3. [ ] 移动Controller到Gateway层
|
||||
4. [ ] 移动DTO到Gateway层的`dto/`目录
|
||||
5. [ ] 移动Guard到Gateway层
|
||||
6. [ ] 创建Gateway Module
|
||||
7. [ ] 更新Business Module,移除Controller
|
||||
8. [ ] 更新imports,修正路径
|
||||
9. [ ] 更新app.module.ts
|
||||
10. [ ] 运行测试确保功能正常
|
||||
|
||||
## 最佳实践
|
||||
|
||||
### 1. 保持层级职责清晰
|
||||
|
||||
每一层只做自己职责范围内的事情,不要越界。
|
||||
|
||||
### 2. 使用统一的响应格式
|
||||
|
||||
Business层返回统一的`ApiResponse<T>`格式:
|
||||
|
||||
```typescript
|
||||
interface ApiResponse<T = any> {
|
||||
success: boolean;
|
||||
data?: T;
|
||||
message: string;
|
||||
error_code?: string;
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 错误处理分层
|
||||
|
||||
- Gateway层:将业务错误转换为HTTP状态码
|
||||
- Business层:捕获异常并转换为业务错误
|
||||
- Core层:抛出技术异常
|
||||
|
||||
### 4. 依赖注入
|
||||
|
||||
使用NestJS的依赖注入系统,通过Module配置依赖关系。
|
||||
|
||||
### 5. 文档完善
|
||||
|
||||
每个层级都应该有README文档说明职责和使用方法。
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **渐进式重构**:不要一次性重构所有模块,逐个模块进行
|
||||
2. **保持测试**:重构后运行测试确保功能正常
|
||||
3. **向后兼容**:重构过程中保持API接口不变
|
||||
4. **代码审查**:重构代码需要经过代码审查
|
||||
5. **文档更新**:及时更新相关文档
|
||||
|
||||
## 参考资料
|
||||
|
||||
- [NestJS官方文档](https://docs.nestjs.com/)
|
||||
- [Clean Architecture](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html)
|
||||
- [Hexagonal Architecture](https://alistair.cockburn.us/hexagonal-architecture/)
|
||||
Reference in New Issue
Block a user