code-quality
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCode Quality
Code Quality
编码和重构时的质量约束,确保代码可维护、可测试、适度扩展。
Quality constraints for coding and refactoring to ensure code is maintainable, testable, and appropriately extensible.
Language
Language
- Accept questions in both Chinese and English
- Always respond in Chinese
- Accept questions in both Chinese and English
- Always respond in Chinese
Trigger Conditions
Trigger Conditions
- 用户正在编写新代码
- 用户需要重构现有代码
- 用户需要 Code Review 检查清单
- 用户提到 MTE 原则、代码质量、避免过度设计
- User is writing new code
- User needs to refactor existing code
- User needs a Code Review checklist
- User mentions MTE principles, code quality, or avoiding over-engineering
核心原则:MTE
Core Principles: MTE
所有代码必须遵循 MTE 原则:
| 原则 | 说明 | 检查点 |
|---|---|---|
| Maintainability | 可维护性 | 职责单一、依赖清晰、易于理解 |
| Testability | 可测试性 | 核心逻辑可单元测试、依赖可 Mock |
| Extensibility | 可扩展性 | 预留合理扩展点、接口抽象 |
All code must follow the MTE Principles:
| Principle | Description | Checkpoints |
|---|---|---|
| Maintainability | Maintainability | Single responsibility, clear dependencies, easy to understand |
| Testability | Testability | Core logic can be unit tested, dependencies can be mocked |
| Extensibility | Extensibility | Reasonable extension points reserved, interface abstraction |
Part 1: 编码约束
Part 1: Coding Constraints
模块设计
Module Design
单一职责
Single Responsibility
✅ 正确:一个类/函数只做一件事
- UserService: 用户业务逻辑
- UserRepository: 用户数据访问
- UserValidator: 用户数据校验
❌ 错误:一个类做多件事
- UserManager: 业务逻辑 + 数据访问 + 校验 + 发送邮件✅ Correct: A class/function does only one thing
- UserService: User business logic
- UserRepository: User data access
- UserValidator: User data validation
❌ Incorrect: A class does multiple things
- UserManager: Business logic + data access + validation + email sending依赖方向
Dependency Direction
┌─────────────────────────────────────┐
│ Interface Layer │ ← 薄层,无业务逻辑
├─────────────────────────────────────┤
│ Service Layer │ ← 业务逻辑(核心)
├─────────────────────────────────────┤
│ Domain Layer │ ← 领域模型
├─────────────────────────────────────┤
│ Infrastructure Layer │ ← 可替换
└─────────────────────────────────────┘
依赖规则:
- 外层依赖内层 ✅
- 内层依赖外层 ❌
- 依赖接口,不依赖实现 ✅┌─────────────────────────────────────┐
│ Interface Layer │ ← Thin layer, no business logic
├─────────────────────────────────────┤
│ Service Layer │ ← Business logic (core)
├─────────────────────────────────────┤
│ Domain Layer │ ← Domain model
├─────────────────────────────────────┤
│ Infrastructure Layer │ ← Replaceable
└─────────────────────────────────────┘
Dependency Rules:
- Outer layers depend on inner layers ✅
- Inner layers depend on outer layers ❌
- Depend on interfaces, not implementations ✅函数设计
Function Design
函数长度
Function Length
- 建议:单个函数不超过 30 行
- 最大:不超过 50 行
- 超过时:拆分为多个小函数
- Recommendation: A single function should not exceed 30 lines
- Maximum: No more than 50 lines
- When exceeded: Split into multiple small functions
参数数量
Parameter Count
- 建议:不超过 3 个参数
- 最大:不超过 5 个参数
- 超过时:使用参数对象
typescript
// ❌ 参数过多
function createUser(name, email, age, role, department, manager) {}
// ✅ 使用参数对象
function createUser(params: CreateUserParams) {}- Recommendation: No more than 3 parameters
- Maximum: No more than 5 parameters
- When exceeded: Use parameter objects
typescript
// ❌ Too many parameters
function createUser(name, email, age, role, department, manager) {}
// ✅ Use parameter object
function createUser(params: CreateUserParams) {}嵌套深度
Nesting Depth
- 建议:不超过 2 层嵌套
- 最大:不超过 3 层嵌套
- 超过时:提取函数或使用早返回
typescript
// ❌ 嵌套过深
if (a) {
if (b) {
if (c) {
// ...
}
}
}
// ✅ 早返回
if (!a) return;
if (!b) return;
if (!c) return;
// ...- Recommendation: No more than 2 levels of nesting
- Maximum: No more than 3 levels of nesting
- When exceeded: Extract functions or use early returns
typescript
// ❌ Excessive nesting
if (a) {
if (b) {
if (c) {
// ...
}
}
}
// ✅ Early return
if (!a) return;
if (!b) return;
if (!c) return;
// ...可测试性设计
Testability Design
详细的测试编写规范请参考/testing-guide
For detailed testing specifications, refer to/testing-guide
核心原则
Core Principles
可测试代码的三个要素:
1. 依赖可注入 - 外部依赖通过参数传入
2. 纯函数优先 - 业务逻辑无副作用
3. 边界分离 - 业务逻辑与 IO 分离Three elements of testable code:
1. Injectable dependencies - External dependencies are passed via parameters
2. Prefer pure functions - Business logic has no side effects
3. Boundary separation - Separate business logic from IO operations依赖注入
Dependency Injection
typescript
// ❌ 硬编码依赖
class UserService {
private db = new Database();
private mailer = new EmailService();
}
// ✅ 依赖注入
class UserService {
constructor(
private db: IDatabase,
private mailer: IEmailService
) {}
}typescript
// ❌ Hard-coded dependencies
class UserService {
private db = new Database();
private mailer = new EmailService();
}
// ✅ Dependency injection
class UserService {
constructor(
private db: IDatabase,
private mailer: IEmailService
) {}
}纯函数优先
Prefer Pure Functions
typescript
// ❌ 有副作用,难测试
function calculateTotal(items) {
const total = items.reduce((sum, item) => sum + item.price, 0);
console.log(`Total: ${total}`); // 副作用
analytics.track('calculate'); // 副作用
return total;
}
// ✅ 纯函数,易测试
function calculateTotal(items) {
return items.reduce((sum, item) => sum + item.price, 0);
}typescript
// ❌ Has side effects, hard to test
function calculateTotal(items) {
const total = items.reduce((sum, item) => sum + item.price, 0);
console.log(`Total: ${total}`); // Side effect
analytics.track('calculate'); // Side effect
return total;
}
// ✅ Pure function, easy to test
function calculateTotal(items) {
return items.reduce((sum, item) => sum + item.price, 0);
}边界分离
Boundary Separation
typescript
// ❌ 业务逻辑混合 IO
async function processOrder(orderId) {
const order = await db.findOrder(orderId); // IO
if (order.total > 1000) { // 业务逻辑
order.discount = 0.1;
}
await db.save(order); // IO
await email.send(order.user, 'confirmed'); // IO
}
// ✅ 分离业务逻辑
function applyDiscount(order) { // 纯业务逻辑,可测试
if (order.total > 1000) {
return { ...order, discount: 0.1 };
}
return order;
}
async function processOrder(orderId) {
const order = await db.findOrder(orderId);
const updated = applyDiscount(order); // 调用纯函数
await db.save(updated);
await email.send(order.user, 'confirmed');
}编写测试时:参考获取断言质量、Mock 策略、变异测试等详细指导/testing-guide
typescript
// ❌ Business logic mixed with IO
async function processOrder(orderId) {
const order = await db.findOrder(orderId); // IO
if (order.total > 1000) { // Business logic
order.discount = 0.1;
}
await db.save(order); // IO
await email.send(order.user, 'confirmed'); // IO
}
// ✅ Separate business logic
function applyDiscount(order) { // Pure business logic, testable
if (order.total > 1000) {
return { ...order, discount: 0.1 };
}
return order;
}
async function processOrder(orderId) {
const order = await db.findOrder(orderId);
const updated = applyDiscount(order); // Call pure function
await db.save(updated);
await email.send(order.user, 'confirmed');
}When writing tests: Refer tofor detailed guidance on assertion quality, mocking strategies, mutation testing, etc./testing-guide
避免过度设计
Avoid Over-Engineering
YAGNI 原则
YAGNI Principle
You Aren't Gonna Need It - 你不会需要它
typescript
// ❌ 过度设计:为假设需求添加配置
const config = {
maxRetries: 3,
retryDelay: 1000,
enableCache: true,
cacheExpiry: 3600,
enableRateLimit: false, // 从未使用
rateLimitWindow: 60000, // 从未使用
enableMetrics: false, // 从未使用
metricsEndpoint: '', // 从未使用
};
// ✅ 只添加当前需要的配置
const config = {
maxRetries: 3,
retryDelay: 1000,
cacheExpiry: 3600,
};You Aren't Gonna Need It
typescript
// ❌ Over-engineering: Adding configurations for hypothetical requirements
const config = {
maxRetries: 3,
retryDelay: 1000,
enableCache: true,
cacheExpiry: 3600,
enableRateLimit: false, // Never used
rateLimitWindow: 60000, // Never used
enableMetrics: false, // Never used
metricsEndpoint: '', // Never used
};
// ✅ Only add configurations needed currently
const config = {
maxRetries: 3,
retryDelay: 1000,
cacheExpiry: 3600,
};抽象时机
Abstraction Timing
❌ 过早抽象:
- 只有一个实现就创建接口
- 只有一处使用就提取函数
- 只有两个相似场景就创建基类
✅ 适时抽象(Rule of Three):
- 3 个以上实现时考虑接口
- 3 处以上重复时考虑提取
- 3 个以上相似场景时考虑基类❌ Premature abstraction:
- Create an interface when there's only one implementation
- Extract a function when it's only used once
- Create a base class when there are only two similar scenarios
✅ Timely abstraction (Rule of Three):
- Consider interfaces when there are 3+ implementations
- Consider extraction when there are 3+ repetitions
- Consider base classes when there are 3+ similar scenarios简单方案优先
Prefer Simple Solutions
typescript
// ❌ 过度设计:简单场景用复杂模式
class UserFactory {
createAdmin() { return new AdminUser(); }
createMember() { return new MemberUser(); }
createGuest() { return new GuestUser(); }
}
// ✅ 简单场景用简单方案
function createUser(role: 'admin' | 'member' | 'guest') {
return { role, permissions: getPermissions(role) };
}typescript
// ❌ Over-engineering: Using complex patterns for simple scenarios
class UserFactory {
createAdmin() { return new AdminUser(); }
createMember() { return new MemberUser(); }
createGuest() { return new GuestUser(); }
}
// ✅ Use simple solutions for simple scenarios
function createUser(role: 'admin' | 'member' | 'guest') {
return { role, permissions: getPermissions(role) };
}设计模式使用
Design Pattern Usage
使用原则
Usage Principles
- 必要时才用:解决实际问题,不为炫技
- 说明理由:为什么选择这个模式
- 保持一致:相同问题用相同模式
- Use only when necessary: Solve actual problems, not for showing off skills
- Explain the reason: Why this pattern was chosen
- Stay consistent: Use the same pattern for the same type of problem
推荐场景
Recommended Scenarios
| 场景 | 推荐模式 | 使用条件 |
|---|---|---|
| 对象创建 | Factory / Builder | 创建逻辑复杂、多种类型 |
| 行为扩展 | Strategy / Template | 算法可替换、流程步骤可变 |
| 结构适配 | Facade / Adapter | 简化接口、适配第三方 |
| 状态管理 | State / Observer | 状态驱动、事件通知 |
| Scenario | Recommended Pattern | Usage Conditions |
|---|---|---|
| Object Creation | Factory / Builder | Complex creation logic, multiple types |
| Behavior Extension | Strategy / Template | Replaceable algorithms, variable process steps |
| Structural Adaptation | Facade / Adapter | Simplify interfaces, adapt third-party systems |
| State Management | State / Observer | State-driven, event notifications |
Part 2: 重构指导
Part 2: Refactoring Guidelines
重构触发条件
Refactoring Trigger Conditions
当代码出现以下 Code Smells 时考虑重构:
Consider refactoring when the code has the following Code Smells:
必须重构
Mandatory Refactoring
| 问题 | 指标 | 重构方向 |
|---|---|---|
| 函数过长 | > 50 行 | 提取函数 |
| 参数过多 | > 5 个 | 参数对象 |
| 嵌套过深 | > 3 层 | 早返回、提取函数 |
| 重复代码 | 3+ 处 | 提取公共逻辑 |
| 上帝类 | > 500 行 | 拆分职责 |
| Issue | Metric | Refactoring Direction |
|---|---|---|
| Long function | > 50 lines | Extract functions |
| Too many parameters | > 5 parameters | Parameter object |
| Excessive nesting | > 3 levels | Early return, extract functions |
| Duplicate code | 3+ occurrences | Extract common logic |
| God class | > 500 lines | Split responsibilities |
建议重构
Recommended Refactoring
| 问题 | 描述 | 重构方向 |
|---|---|---|
| 特性依恋 | 频繁访问其他类数据 | 移动方法 |
| 数据泥团 | 多个参数总是一起出现 | 提取类 |
| 霰弹式修改 | 一个改动影响多处 | 集中逻辑 |
| 平行继承 | 每次加子类要加配套类 | 合并层次 |
| Issue | Description | Refactoring Direction |
|---|---|---|
| Feature envy | Frequent access to other class data | Move method |
| Data clumps | Multiple parameters always appear together | Extract class |
| Shotgun surgery | A single change affects multiple places | Centralize logic |
| Parallel inheritance | Adding a subclass requires adding a matching class | Merge hierarchies |
重构流程
Refactoring Process
1. 确保测试覆盖
│
├── 有测试 → 继续
└── 无测试 → 先补充测试
│
▼
2. 小步重构
│
├── 每次只改一件事
├── 每步都能运行
└── 每步都运行测试
│
▼
3. 验证行为不变
│
├── 测试全部通过
└── 手动验证关键路径
│
▼
4. 提交代码1. Ensure test coverage
│
├── Has tests → Proceed
└── No tests → Add tests first
│
▼
2. Small-step refactoring
│
├── Only change one thing at a time
├── Ensure code runs after each step
└── Run tests after each step
│
▼
3. Verify unchanged behavior
│
├── All tests pass
└── Manually verify critical paths
│
▼
4. Commit code重构约束
Refactoring Constraints
安全约束
Safety Constraints
- 重构前必须有测试覆盖
- 每步重构后运行测试
- 不在重构中添加新功能
- 不在添加功能时重构
- Must have test coverage before refactoring
- Run tests after each refactoring step
- Do not add new features during refactoring
- Do not refactor while adding new features
范围约束
Scope Constraints
- 单次重构只改一类问题
- 单次 PR 只包含一个重构主题
- 大范围重构需要分阶段进行
- Only fix one type of issue per refactoring
- Only include one refactoring theme per PR
- Large-scale refactoring needs to be phased
风险评估
Risk Assessment
| 风险等级 | 条件 | 策略 |
|---|---|---|
| 低 | 有完善测试、改动局部 | 直接重构 |
| 中 | 部分测试、影响多处 | 先补测试 |
| 高 | 无测试、核心逻辑 | 逐步添加测试后重构 |
| Risk Level | Conditions | Strategy |
|---|---|---|
| Low | Complete test coverage, localized changes | Refactor directly |
| Medium | Partial test coverage, affects multiple places | Add tests first |
| High | No test coverage, core logic | Gradually add tests before refactoring |
Part 3: Code Review 清单
Part 3: Code Review Checklist
Review 前置检查
Pre-Review Checks
- PR 描述清晰说明改动内容和原因
- CI 通过(测试、lint、build)
- 改动范围合理(单一主题)
- PR description clearly explains the changes and reasons
- CI passes (tests, lint, build)
- Reasonable scope of changes (single theme)
代码质量检查
Code Quality Checks
MTE 原则
MTE Principles
-
M - 可维护性
- 函数职责单一
- 命名清晰准确
- 依赖关系清晰
-
T - 可测试性
- 核心逻辑有测试
- 依赖可以 Mock
- 边界条件覆盖
-
E - 可扩展性
- 预留合理扩展点
- 不为假设需求设计
- 配置合理
-
M - Maintainability
- Single function responsibility
- Clear and accurate naming
- Clear dependency relationships
-
T - Testability
- Core logic has tests
- Dependencies can be mocked
- Boundary conditions are covered
-
E - Extensibility
- Reasonable extension points reserved
- No design for hypothetical requirements
- Reasonable configurations
代码规范
Code Standards
- 函数长度 < 50 行
- 参数数量 < 5 个
- 嵌套深度 < 3 层
- 无重复代码
- 无硬编码敏感信息
- Function length < 50 lines
- Parameter count < 5
- Nesting depth < 3 levels
- No duplicate code
- No hard-coded sensitive information
错误处理
Error Handling
- 边界条件处理
- 错误信息有意义
- 不吞掉异常
- Boundary conditions handled
- Error messages are meaningful
- No swallowed exceptions
安全检查
Security Checks
- 无 SQL 注入风险
- 无 XSS 风险
- 敏感数据加密/脱敏
- 权限控制正确
- No SQL injection risks
- No XSS risks
- Sensitive data encrypted/desensitized
- Correct permission control
Review 反馈分级
Review Feedback Classification
| 级别 | 标记 | 含义 | 要求 |
|---|---|---|---|
| 阻塞 | | 必须修复才能合并 | 安全问题、逻辑错误 |
| 建议 | | 建议修改但不阻塞 | 代码风格、小优化 |
| 疑问 | | 需要作者解释 | 不理解的设计决策 |
| 赞 | | 写得好的地方 | 鼓励好的实践 |
| Level | Tag | Meaning | Requirements |
|---|---|---|---|
| Blocker | | Must be fixed before merging | Security issues, logical errors |
| Suggestion | | Recommended change but not blocking | Code style, minor optimizations |
| Question | | Requires explanation from author | Unclear design decisions |
| Praise | | Well-written parts | Encourage good practices |
Part 4: 应用场景
Part 4: Application Scenarios
场景 1: 编写新代码
Scenario 1: Writing New Code
当用户编写新代码时,自动应用以下约束:
- 模块设计:检查职责是否单一
- 函数设计:检查长度、参数、嵌套
- 可测试性:检查依赖是否可注入
- 避免过度设计:检查是否 YAGNI
When a user is writing new code, automatically apply the following constraints:
- Module Design: Check if responsibilities are single
- Function Design: Check length, parameters, and nesting
- Testability: Check if dependencies are injectable
- Avoid Over-Engineering: Check if YAGNI is followed
场景 2: 重构现有代码
Scenario 2: Refactoring Existing Code
当用户要求重构时:
- 评估风险:检查测试覆盖
- 识别问题:找出 Code Smells
- 制定计划:确定重构步骤
- 小步执行:每步运行测试
When a user requests refactoring:
- Risk Assessment: Check test coverage
- Identify Issues: Find Code Smells
- Develop Plan: Determine refactoring steps
- Execute in Small Steps: Run tests after each step
场景 3: Code Review
Scenario 3: Code Review
当用户要求审查代码时:
- 使用清单:逐项检查
- 分级反馈:区分阻塞和建议
- 说明理由:解释为什么这样建议
When a user requests code review:
- Use Checklist: Check item by item
- Classify Feedback: Distinguish between blockers and suggestions
- Explain Reasons: Explain why the suggestion is made
Constraints
Constraints
编码约束
Coding Constraints
- 函数不超过 50 行
- 参数不超过 5 个
- 嵌套不超过 3 层
- 依赖通过注入,不硬编码
- 核心逻辑可单元测试
- Functions no longer than 50 lines
- No more than 5 parameters
- Nesting depth no more than 3 levels
- Dependencies injected, not hard-coded
- Core logic unit testable
设计约束
Design Constraints
- 每个模块职责单一
- 依赖方向:外层依赖内层
- 不为假设需求设计
- 3 个以上相似场景才抽象
- Each module has a single responsibility
- Dependency direction: Outer layers depend on inner layers
- No design for hypothetical requirements
- Abstract only when there are 3+ similar scenarios
重构约束
Refactoring Constraints
- 重构前必须有测试
- 每步重构后运行测试
- 不在重构中添加功能
- Must have tests before refactoring
- Run tests after each refactoring step
- Do not add features during refactoring
Review 约束
Review Constraints
- 区分阻塞和建议
- 反馈需要说明理由
- 安全问题必须阻塞
- Distinguish between blockers and suggestions
- Feedback must include reasons
- Security issues must be blockers