Files
whale-town-end/docs/ARCHITECTURE_REFACTORING.md
moyin a147883e05 docs:添加架构重构文档
- 新增 ARCHITECTURE_REFACTORING.md 文档
- 记录项目架构重构计划和进度
2026-01-14 13:17:53 +08:00

7.4 KiB
Raw Permalink Blame History

架构重构文档

重构目标

将现有的混合架构重构为清晰的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进行数据验证
  • 统一的错误处理
  • 不直接访问数据库
  • 不包含业务规则

示例

@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协议
  • 不直接访问数据库

示例

@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>格式:

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. 文档更新:及时更新相关文档

参考资料