1
0
Files
Encoding-Specification/README.md
2025-08-22 15:26:45 +08:00

210 lines
9.1 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.
# 编码规范
> 目标:统一团队的编码风格、工程结构、质量门槛与评审流程,降低维护成本并提升可读性与安全性。
---
## 总体原则(适用于所有语言)
- **一致优先**:团队内以本规范为准;历史代码可在“动则改之”的前提下逐步迁移。
- **自动化为先**:全部项目必须配置“格式化+ 单元测试”,并在 CI 强制执行。
- **最小接口**:公开 API 保持最小化,隐藏实现细节;遵循“只暴露需要被依赖的东西”。
- **可读性**:命名清晰、函数短小(通常 ≤ 40 行),模块单一职责。
- **防御式编程**:显式边界检查、错误处理、输入校验、超时与重试策略。
- **不可变优先**:能用不可变结构/值对象则优先使用;避免可变全局状态。
- **安全默认**:启用严格编译/类型校验、依赖锁定与安全基线(见各语言安全节)。
- **文档与注释**:公开类型/函数必须有 API 文档;复杂逻辑用块注释解释“为什么”。
- **提交规范**:见 [Git 管理规范](https://gitea.fireflydt.com/docs/Git-Management)。
- **代码评审**:至少 1 名 Reviewer禁止自我合并高风险改动需 2 人评审与灰度。
---
## Java 规范
### 版本与工具
- 运行时:**Java 24+**。
- 构建: Maven统一使用 Wrapper。
### 代码风格
- 缩进 **4 空格**;最大行宽 **120**UTF-8Unix 换行;文件末尾保留换行。
- 包名 `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. 可维护性:日志可观测、告警/指标完善、特性开关与回滚预案。