Files
whale-town-end/docs/development/naming_convention.md
moyin 85d488a508 docs: 重构文档结构和组织
- 重新组织docs目录结构,按功能模块分类
- 新增deployment和development目录
- 更新API文档结构
- 添加客户端README文档
- 移除过时的文档文件
2025-12-24 18:04:14 +08:00

528 lines
11 KiB
Markdown
Raw Permalink 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.
# 命名规范
本文档定义了项目中所有代码的命名规范,确保代码风格统一,提高可读性和可维护性。
## 目录
- [文件和文件夹命名](#文件和文件夹命名)
- [变量和函数命名](#变量和函数命名)
- [类和构造函数命名](#类和构造函数命名)
- [常量命名](#常量命名)
- [接口路由命名](#接口路由命名)
- [TypeScript 特定规范](#typescript-特定规范)
- [命名示例](#命名示例)
## 文件和文件夹命名
**规则使用下划线分隔snake_case**
### 文件命名
```
✅ 正确示例:
- order_controller.ts
- user_service.ts
- game_gateway.ts
- player_entity.ts
- create_room_dto.ts
- database_config.ts
❌ 错误示例:
- OrderController.ts
- userService.ts
- game-gateway.ts
- playerEntity.ts
```
### 文件夹命名
```
✅ 正确示例:
- src/api/
- src/service/
- src/model/dto/
- src/utils/
- src/config/
- test/unit_test/
- test/integration_test/
❌ 错误示例:
- src/API/
- src/Service/
- src/model-dto/
- src/Utils/
```
### 特殊说明
- 所有文件和文件夹名使用小写字母
- 多个单词之间使用下划线 `_` 连接
- 避免使用缩写,除非是广泛认可的缩写(如 dto、api
## 变量和函数命名
**规则使用小驼峰命名camelCase**
### 变量命名
```typescript
const userName = 'Alice';
let playerScore = 100;
const roomId = '12345';
const isGameStarted = false;
const maxPlayerCount = 4;
const UserName = 'Alice';
const player_score = 100;
const RoomId = '12345';
const is_game_started = false;
```
### 函数命名
```typescript
function getUserInfo() { }
async function queryUserInfo() { }
function calculateDamage() { }
function isPlayerAlive() { }
function handlePlayerMove() { }
function GetUserInfo() { }
function query_user_info() { }
function CalculateDamage() { }
function IsPlayerAlive() { }
```
### 命名建议
- 使用动词开头描述函数功能:
- `get` - 获取数据(如 `getUserById`
- `set` - 设置数据(如 `setPlayerPosition`
- `create` - 创建实体(如 `createRoom`
- `update` - 更新数据(如 `updatePlayerScore`
- `delete` - 删除数据(如 `deleteRoom`
- `is/has` - 布尔判断(如 `isGameOver``hasPermission`
- `handle` - 事件处理(如 `handlePlayerAttack`
- `calculate` - 计算逻辑(如 `calculateDamage`
- `validate` - 验证逻辑(如 `validateInput`
- 布尔变量使用 `is``has``can` 等前缀:
```typescript
const isActive = true;
const hasPermission = false;
const canMove = true;
```
## 类和构造函数命名
**规则使用大驼峰命名PascalCase**
### 类命名
```typescript
✅ 正确示例:
class UserModel { }
class OrderService { }
class GameController { }
class PlayerEntity { }
class RoomGateway { }
class DatabaseConnection { }
❌ 错误示例:
class userModel { }
class order_service { }
class gameController { }
class player_entity { }
```
### 接口命名
```typescript
✅ 正确示例:
interface User { }
interface GameConfig { }
interface PlayerData { }
interface RoomOptions { }
// 或使用 I 前缀(可选)
interface IUser { }
interface IGameConfig { }
❌ 错误示例:
interface user { }
interface game_config { }
interface playerData { }
```
### DTO 命名
```typescript
✅ 正确示例:
class CreateUserDto { }
class UpdatePlayerDto { }
class JoinRoomDto { }
class GameStateDto { }
❌ 错误示例:
class createUserDto { }
class update_player_dto { }
class joinRoomDTO { }
```
### 装饰器命名
```typescript
✅ 正确示例:
@Controller('users')
@Injectable()
@Module()
@Get()
// 自定义装饰器
function CustomDecorator() { }
```
## 常量命名
**规则:全大写 + 下划线分隔SCREAMING_SNAKE_CASE**
```typescript
✅ 正确示例:
const PORT = 3000;
const DB_HOST = 'localhost';
const MAX_PLAYERS = 10;
const API_VERSION = 'v1';
const DEFAULT_TIMEOUT = 5000;
const GAME_STATUS_WAITING = 'waiting';
const GAME_STATUS_PLAYING = 'playing';
❌ 错误示例:
const port = 3000;
const dbHost = 'localhost';
const maxPlayers = 10;
const ApiVersion = 'v1';
const default_timeout = 5000;
```
### 枚举命名
```typescript
✅ 正确示例:
enum GameStatus {
WAITING = 'waiting',
PLAYING = 'playing',
FINISHED = 'finished',
}
enum PlayerRole {
ADMIN = 'admin',
PLAYER = 'player',
SPECTATOR = 'spectator',
}
❌ 错误示例:
enum gameStatus {
waiting = 'waiting',
playing = 'playing',
}
enum PlayerRole {
admin = 'admin',
player = 'player',
}
```
## 接口路由命名
**规则:全小写 + 短横线分隔kebab-case**
```typescript
✅ 正确示例:
@Get('user/get-info')
@Post('order/create-order')
@Put('player/update-position')
@Delete('room/delete-room')
@Get('game/get-state')
@Post('room/join-room')
❌ 错误示例:
@Get('user/getInfo')
@Post('order/createOrder')
@Put('player/update_position')
@Delete('room/DeleteRoom')
@Get('game/GetState')
```
### 路由结构建议
```typescript
// 资源型路由
@Controller('api/players')
export class PlayerController {
@Get() // GET /api/players
@Get(':id') // GET /api/players/:id
@Post() // POST /api/players
@Put(':id') // PUT /api/players/:id
@Delete(':id') // DELETE /api/players/:id
}
// 动作型路由
@Controller('api/game')
export class GameController {
@Post('start-game') // POST /api/game/start-game
@Post('end-game') // POST /api/game/end-game
@Get('get-state') // GET /api/game/get-state
}
// 嵌套资源路由
@Controller('api/rooms')
export class RoomController {
@Post(':id/join') // POST /api/rooms/:id/join
@Post(':id/leave') // POST /api/rooms/:id/leave
@Get(':id/players') // GET /api/rooms/:id/players
}
```
## TypeScript 特定规范
### 类型别名
```typescript
✅ 正确示例:
type UserId = string;
type PlayerPosition = { x: number; y: number };
type GameCallback = (state: GameState) => void;
❌ 错误示例:
type userId = string;
type player_position = { x: number; y: number };
```
### 泛型参数
```typescript
✅ 正确示例:
function findById<T>(id: string): T { }
class Repository<T, K> { }
interface Response<T> { }
// 使用有意义的名称
function mapArray<TInput, TOutput>(arr: TInput[]): TOutput[] { }
❌ 错误示例:
function findById<t>(id: string): t { }
class Repository<type, key> { }
```
### 装饰器参数
```typescript
✅ 正确示例:
@Column({ name: 'user_name' })
@IsString({ message: 'Name must be a string' })
@ApiProperty({ description: 'User ID' })
❌ 错误示例:
@Column({ name: 'UserName' })
@IsString({ message: 'name_must_be_string' })
```
## 命名示例
### 完整的模块示例
```typescript
// 文件src/api/player_controller.ts
import { Controller, Get, Post, Body, Param } from '@nestjs/common';
import { PlayerService } from '../service/player_service';
import { CreatePlayerDto } from '../model/dto/create_player_dto';
const MAX_PLAYERS = 100;
@Controller('api/players')
export class PlayerController {
constructor(private readonly playerService: PlayerService) {}
@Get()
async getAllPlayers() {
return this.playerService.findAll();
}
@Get(':id')
async getPlayerById(@Param('id') playerId: string) {
return this.playerService.findById(playerId);
}
@Post()
async createPlayer(@Body() createPlayerDto: CreatePlayerDto) {
return this.playerService.create(createPlayerDto);
}
@Post(':id/update-position')
async updatePlayerPosition(
@Param('id') playerId: string,
@Body() body: { x: number; y: number }
) {
const { x, y } = body;
return this.playerService.updatePosition(playerId, x, y);
}
}
```
```typescript
// 文件src/service/player_service.ts
import { Injectable, NotFoundException } from '@nestjs/common';
import { Player } from '../model/player_entity';
import { CreatePlayerDto } from '../model/dto/create_player_dto';
const DEFAULT_HEALTH = 100;
const DEFAULT_SPEED = 5;
@Injectable()
export class PlayerService {
private players: Map<string, Player> = new Map();
findAll(): Player[] {
return Array.from(this.players.values());
}
findById(playerId: string): Player {
const player = this.players.get(playerId);
if (!player) {
throw new NotFoundException(`Player with ID ${playerId} not found`);
}
return player;
}
create(createPlayerDto: CreatePlayerDto): Player {
const newPlayer: Player = {
id: this.generatePlayerId(),
name: createPlayerDto.name,
health: DEFAULT_HEALTH,
speed: DEFAULT_SPEED,
position: { x: 0, y: 0 },
isAlive: true,
createdAt: new Date(),
};
this.players.set(newPlayer.id, newPlayer);
return newPlayer;
}
updatePosition(playerId: string, x: number, y: number): Player {
const player = this.findById(playerId);
player.position = { x, y };
return player;
}
private generatePlayerId(): string {
return `player_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
}
private calculateDamage(attackPower: number, defense: number): number {
return Math.max(0, attackPower - defense);
}
isPlayerAlive(playerId: string): boolean {
const player = this.findById(playerId);
return player.isAlive && player.health > 0;
}
}
```
```typescript
// 文件src/model/player_entity.ts
export interface Player {
id: string;
name: string;
health: number;
speed: number;
position: Position;
isAlive: boolean;
createdAt: Date;
}
export interface Position {
x: number;
y: number;
}
export enum PlayerStatus {
IDLE = 'idle',
MOVING = 'moving',
ATTACKING = 'attacking',
DEAD = 'dead',
}
```
```typescript
// 文件src/model/dto/create_player_dto.ts
import { IsString, IsNotEmpty, MinLength, MaxLength } from 'class-validator';
export class CreatePlayerDto {
@IsString()
@IsNotEmpty()
@MinLength(3)
@MaxLength(20)
name: string;
}
```
## 检查清单
在提交代码前,请确保:
- [ ] 所有文件和文件夹使用下划线分隔命名
- [ ] 所有变量和函数使用小驼峰命名
- [ ] 所有类、接口、DTO 使用大驼峰命名
- [ ] 所有常量和枚举值使用全大写 + 下划线命名
- [ ] 所有路由使用全小写 + 短横线命名
- [ ] 函数名清晰表达其功能
- [ ] 布尔变量使用 is/has/can 前缀
- [ ] 避免使用无意义的缩写
## 工具配置
### ESLint 配置建议
```json
{
"rules": {
"@typescript-eslint/naming-convention": [
"error",
{
"selector": "variable",
"format": ["camelCase", "UPPER_CASE"]
},
{
"selector": "function",
"format": ["camelCase"]
},
{
"selector": "class",
"format": ["PascalCase"]
},
{
"selector": "interface",
"format": ["PascalCase"]
}
]
}
}
```
## 总结
遵循统一的命名规范能够:
- 提高代码可读性
- 减少团队沟通成本
- 降低代码维护难度
- 避免命名冲突
- 提升项目专业度
记住:**好的命名是自解释的,不需要额外的注释。**