210 lines
9.1 KiB
Markdown
210 lines
9.1 KiB
Markdown
# 编码规范
|
||
|
||
> 目标:统一团队的编码风格、工程结构、质量门槛与评审流程,降低维护成本并提升可读性与安全性。
|
||
|
||
---
|
||
|
||
## 总体原则(适用于所有语言)
|
||
|
||
- **一致优先**:团队内以本规范为准;历史代码可在“动则改之”的前提下逐步迁移。
|
||
- **自动化为先**:全部项目必须配置“格式化+ 单元测试”,并在 CI 强制执行。
|
||
- **最小接口**:公开 API 保持最小化,隐藏实现细节;遵循“只暴露需要被依赖的东西”。
|
||
- **可读性**:命名清晰、函数短小(通常 ≤ 40 行),模块单一职责。
|
||
- **防御式编程**:显式边界检查、错误处理、输入校验、超时与重试策略。
|
||
- **不可变优先**:能用不可变结构/值对象则优先使用;避免可变全局状态。
|
||
- **安全默认**:启用严格编译/类型校验、依赖锁定与安全基线(见各语言安全节)。
|
||
- **文档与注释**:公开类型/函数必须有 API 文档;复杂逻辑用块注释解释“为什么”。
|
||
- **提交规范**:见 [Git 管理规范](https://gitea.fireflydt.com/docs/Git-Management)。
|
||
- **代码评审**:至少 1 名 Reviewer;禁止自我合并;高风险改动需 2 人评审与灰度。
|
||
|
||
---
|
||
|
||
## Java 规范
|
||
|
||
### 版本与工具
|
||
- 运行时:**Java 24+**。
|
||
- 构建: Maven;统一使用 Wrapper。
|
||
|
||
### 代码风格
|
||
- 缩进 **4 空格**;最大行宽 **120**;UTF-8;Unix 换行;文件末尾保留换行。
|
||
- 包名 `com.example.app` **全小写**;类/接口/枚举 **PascalCase**;方法/变量 **camelCase**;常量 **UPPER_SNAKE_CASE**。
|
||
- `import` 不使用通配符;分组顺序:`java.*`、`javax.*`、第三方、公司内部,组间空行。
|
||
- 注解每行一个;参数较多时每个参数换行对齐。
|
||
|
||
### 语言与设计实践
|
||
- **可空性**:参数尽量非空;需要可空用 `@Nullable`;返回值可空时优先 `Optional<T>`(集合返回空集合)。
|
||
- **异常**:
|
||
- 仅对可恢复情形使用受检异常;不可恢复用 `RuntimeException` 派生。
|
||
- 禁止吞异常;记录日志并保留根因:`throw new FooException("msg", e)`。
|
||
- **集合与不可变**:优先接口类型(`List`, `Map`);尽量使用不可变集合(`List.of()` / Guava Immutable)。
|
||
- **并发**:优先 `Executors`/`CompletableFuture`/`java.util.concurrent`; 避免低层 `synchronized` 共享可变状态。
|
||
- **记录日志**:使用 SLF4J;结构化日志键值对;禁止输出敏感信息。
|
||
- **注释与文档**:公共 API 使用 Javadoc(`/** … */`),首句为概述,包含 `@param`/`@return`/`@throws`。
|
||
|
||
### 工程结构
|
||
```
|
||
app/
|
||
src/main/java/...
|
||
src/main/resources/...
|
||
src/test/java/...
|
||
```
|
||
|
||
### 示例
|
||
```java
|
||
public final class UserService {
|
||
private final UserRepo repo;
|
||
|
||
public UserService(UserRepo repo) { this.repo = Objects.requireNonNull(repo); }
|
||
|
||
/** 根据 ID 查询用户,未找到返回 Optional.empty()。 */
|
||
public Optional<User> findById(long id) {
|
||
if (id <= 0) throw new IllegalArgumentException("id must be positive");
|
||
return repo.find(id);
|
||
}
|
||
}
|
||
```
|
||
|
||
|
||
### 测试
|
||
- 单元测试覆盖关键分支;使用 Mockito 隔离外部依赖;集成测试使用 Testcontainers。
|
||
|
||
---
|
||
|
||
## Dart / Flutter 规范
|
||
|
||
### 版本与工具
|
||
- Dart **3+**(空安全);格式化:`dart format`;静态检查:`dart analyze`;测试:`dart test`/`flutter test`。
|
||
|
||
### 风格与规则
|
||
- 行宽 **100**;缩进 2 空格;字符串默认 **单引号**;使用 **尾随逗号** 触发友好换行。
|
||
- 命名:类/枚举 **PascalCase**;成员/变量 **lowerCamelCase**;常量 **lowerCamelCase** 或 `kPascalCase`(团队统一其一)。
|
||
- `import` 使用包前缀;避免相对路径越级;公共库通过 `lib/` 暴露 API。
|
||
|
||
### 语言实践
|
||
- **空安全**:用 `T?`、`late` 谨慎;尽量用 `required` 命名参数;返回空集合而非 `null`。
|
||
- **不可变**:优先 `const` 构造与 `final` 字段;值对象使用 `equatable` 或 `records`(Dart 3)。
|
||
- **错误处理**:UI 层捕获并展示;领域/数据层返回 `Result`/`Either` 或抛出受控异常。
|
||
|
||
### Flutter 特定
|
||
- `build()` 保持轻量;提取小部件;避免在 `build` 里做副作用。
|
||
- **状态管理**:使用 Provider,全局一致;不可混搭多套范式。
|
||
- **主题与可访问性**:统一 `ThemeData`;文字遵循最小触达 44x44;支持深色模式与本地化。
|
||
|
||
### 示例
|
||
```dart
|
||
class UserTile extends StatelessWidget {
|
||
const UserTile({super.key, required this.user});
|
||
final User user;
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
return ListTile(title: Text(user.name), subtitle: Text(user.email));
|
||
}
|
||
}
|
||
```
|
||
|
||
### 工程与测试
|
||
- 目录:`lib/`, `test/`, `integration_test/`;导出统一入口 `lib/<package>.dart`。
|
||
|
||
### 安全
|
||
- `flutter_secure_storage` 存放机密;禁用在客户端拼接 SQL。
|
||
|
||
---
|
||
|
||
## PHP 规范
|
||
|
||
### 版本与工具
|
||
- PHP **8.3+**;启用 `declare(strict_types=1);`
|
||
- 标准:**PSR-12**(编码风格)、**PSR-4**(自动加载)。
|
||
|
||
### 风格
|
||
- 缩进 4 空格;行宽 120;文件使用 `<?php`,**无 close tag**;每文件单一类。
|
||
- 命名空间必需;类/接口/特性 **PascalCase**;方法/变量 **camelCase**;常量 **UPPER_SNAKE_CASE**。
|
||
|
||
### 语言实践
|
||
- **类型**:所有函数/属性声明类型;返回类型必须标注;尽量使用 `readonly`/`enum`。
|
||
- **错误处理**:仅在边界层捕获并转换为 HTTP/CLI 语义;日志使用 Monolog;禁止 `@` 错误抑制。
|
||
- **依赖注入**:框架(如 Laravel/Symfony)遵循容器注入;禁止在构造中做重 IO。
|
||
|
||
### 示例
|
||
```php
|
||
<?php declare(strict_types=1);
|
||
|
||
namespace App\Service;
|
||
|
||
final class UserService {
|
||
public function __construct(private UserRepo $repo) {}
|
||
|
||
/** @return list<User> */
|
||
public function list(): array {
|
||
return $this->repo->all();
|
||
}
|
||
}
|
||
```
|
||
|
||
### 安全
|
||
- 使用 **PDO**/ORM 预处理;绝不拼接 SQL;`password_hash`/`password_verify`;默认关闭 `display_errors`,仅记录日志。
|
||
|
||
### 测试
|
||
- PHPUnit + Testdouble;对控制器使用特性/内核测试(框架自带)。
|
||
|
||
---
|
||
|
||
## C# / .NET 规范
|
||
|
||
### 版本与工具
|
||
- .NET **8.0+**;启用 **Nullable Reference Types**;项目使用 SDK-style `csproj`。
|
||
- 格式化:`dotnet format`;分析器:Roslyn + StyleCop.Analyzers;测试:xUnit(首选)或 NUnit/MSTest。
|
||
|
||
### 风格
|
||
- 文件作用域命名空间:`namespace Foo.Bar;`
|
||
- 命名:类型/属性/方法 **PascalCase**;局部/参数 **camelCase**;私有字段 `_camelCase`;常量 **PascalCase**。
|
||
- `var` 用于显而易见类型;`async` 方法以 **Async** 结尾,返回 `Task`/`Task<T>`。
|
||
- `using` 顶部排序;启用**顶级语句**仅限简单程序。
|
||
|
||
### 语言与设计
|
||
- 优先 **记录(record)** 表示不可变值对象;表达式体成员简化;模式匹配与 `switch` 表达式提升可读性。
|
||
- 依赖注入:`Microsoft.Extensions.DependencyInjection`;配置通过 Options 模式强类型化。
|
||
- 错误处理:显式捕获特定异常;使用 `ILogger` 结构化日志;禁止空 catch。
|
||
|
||
### 示例
|
||
```csharp
|
||
public sealed record User(Guid Id, string Name);
|
||
|
||
public sealed class UserService
|
||
{
|
||
private readonly IUserRepo _repo;
|
||
public UserService(IUserRepo repo) => _repo = repo ?? throw new ArgumentNullException(nameof(repo));
|
||
|
||
public async Task<User?> FindAsync(Guid id, CancellationToken ct) => await _repo.FindAsync(id, ct);
|
||
}
|
||
```
|
||
|
||
### 安全
|
||
- 默认启用 HTTPS/HSTS;参数绑定使用验证特性(FluentValidation/DataAnnotations);机密用 `IConfiguration` + Secret Manager/Azure Key Vault。
|
||
- 依赖通过 `Directory.Packages.props` 统一管理;开启 `dotnet list package --vulnerable`。
|
||
|
||
### 测试
|
||
- xUnit:遵循 AAA;使用 `WebApplicationFactory` 做 API 集成测试;使用 `NSubstitute`/`Moq`。
|
||
|
||
---
|
||
|
||
## 安全与隐私基线(通用)
|
||
|
||
- 秘密管理:禁止将密钥/令牌写入仓库;使用环境变量与密钥管理服务(Vault/Key Vault/Secrets Manager)。
|
||
- 日志脱敏:邮箱、手机号、身份证、token、cookie 等敏感字段做掩码;遵循最小留存周期。
|
||
- 依赖治理:启用锁文件(`go.sum`/`composer.lock`/`gradle.lockfile`/`Directory.Packages.props`),定期更新并审计。
|
||
- 输入校验:所有外部输入均视为不可信,进行白名单/模式/长度校验。
|
||
- 传输安全:默认 HTTPS/TLS1.2+;启用 HSTS/CSRF 防护/同源策略;Cookie 设置 `HttpOnly`、`Secure`、`SameSite`。
|
||
|
||
---
|
||
|
||
## 代码评审清单(适用于所有 PR)
|
||
|
||
1. 语义:命名准确、注释到位、公共 API 有文档。
|
||
2. 架构:单一职责、模块边界清晰、依赖方向正确、可测试性良好。
|
||
3. 风格:符合对应语言规范;无“魔法数”;函数不超长;重复代码已抽取。
|
||
4. 错误与边界:错误处理全面;边界条件测试齐全;超时/重试/幂等等策略明确。
|
||
5. 安全:输入校验、权限校验、敏感信息保护、依赖与许可证合规。
|
||
6. 性能:无不必要的 I/O/分配;关键路径有基准或指标。
|
||
7. 可维护性:日志可观测、告警/指标完善、特性开关与回滚预案。 |