名称:工程基础 描述:代码质量的基础知识。应用于审查命名规范、DRY、SOLID、函数大小、重构,或当初级开发者问“这干净吗”、“代码审查”、“更好的方式”。 用户可调用:否
工程基础审查
“代码被阅读的次数比编写的次数多。为读者写代码,而不是为机器。”
何时应用
在审查时激活此技能:
- 任何代码变更
- 函数和变量命名
- 代码组织和结构
- 一般重构决策
审查清单
命名
- [ ] 描述性:你能在没有上下文的情况下理解变量吗?
- [ ] 无缩写:名称是否拼写完整?(使用
user而不是usr) - [ ] 无通用名称:没有
data、temp、info、stuff? - [ ] 布尔前缀:布尔值是否以
is、has、can、should开头? - [ ] 函数动词:函数是否以动作动词开头?
函数设计
- [ ] 单一职责:每个函数是否只做一件事?
- [ ] 大小限制:函数是否控制在20-30行以内?
- [ ] 参数数量:是否有少于4个参数?
- [ ] 无副作用:纯函数是否真的纯净?
- [ ] 提前返回:是否使用保护子句代替深层嵌套?
代码组织
- [ ] DRY原则:重复代码是否提取为函数?
- [ ] 但不过度DRY:抽象是否合理(三次规则)?
- [ ] 内聚性:相关事物是否分组在一起?
- [ ] 分离性:不相关事物是否分开?
注释与文档
- [ ] 为什么,而不是什么:注释是否解释原因,而不是明显代码?
- [ ] 无注释掉代码:死代码是否删除,而非注释?
- [ ] 公共API的JSDoc:导出函数是否文档化?
常见错误(反模式)
1. 魔法数字
❌ if (status === 2) { ... }
setTimeout(callback, 86400000);
✅ const STATUS = { ACTIVE: 2, INACTIVE: 1 };
if (status === STATUS.ACTIVE) { ... }
const ONE_DAY_MS = 24 * 60 * 60 * 1000;
setTimeout(callback, ONE_DAY_MS);
2. 不清晰命名
❌ const d = new Date();
const temp = getUser();
const flag = true;
✅ const createdAt = new Date();
const currentUser = getUser();
const isAuthenticated = true;
3. 上帝函数
❌ function processOrder(order) {
// 200行:验证、计算、保存、邮件、日志...
}
✅ function processOrder(order) {
validateOrder(order);
const total = calculateTotal(order);
await saveOrder(order, total);
await sendConfirmationEmail(order);
logOrderProcessed(order);
}
4. 深层嵌套
❌ function check(user) {
if (user) {
if (user.active) {
if (user.role === 'admin') {
return true;
}
}
}
return false;
}
✅ function check(user) {
if (!user) return false;
if (!user.active) return false;
if (user.role !== 'admin') return false;
return true;
}
5. 过早抽象
❌ // 只使用一次,但有10个配置选项
createFlexibleReusableButton({ ... });
✅ // 直接制作按钮
<button className="primary">提交</button>
// 当需要3次以上时再抽象
SOLID原则快速检查
| 原则 | 问题 | 红色标志 |
|---|---|---|
| 单一职责 | “这个类/函数是否做一件事?” | 类有10个以上方法 |
| 开闭原则 | “我能不修改就扩展吗?” | 类型switch语句 |
| 里氏替换 | “我能交换实现吗?” | 重写方法破坏契约 |
| 接口隔离 | “接口是否聚焦?” | 客户端被迫依赖未使用方法 |
| 依赖倒置 | “高层模块是否依赖抽象?” | 直接实例化依赖 |
苏格拉底式提问
向初级开发者问这些问题而不是给出答案:
- 命名:“新开发者在没有上下文的情况下能理解这个名称吗?”
- 函数大小:“你能用一句话描述这个函数做什么吗?”
- 重复:“我看到这个模式出现在三个地方。如果需要更改,会发生什么?”
- 抽象:“这个抽象实际上使用了多少次?”
- 可读性:“如果你6个月后回看这段代码,你会理解它吗?”
命名约定
| 类型 | 约定 | 示例 |
|---|---|---|
| 变量 | camelCase | userName, isActive |
| 常量 | UPPER_SNAKE_CASE | MAX_RETRIES, API_URL |
| 函数 | camelCase + 动词 | getUser(), handleSubmit() |
| 类 | PascalCase | UserService, AuthProvider |
| 文件(组件) | PascalCase | UserProfile.tsx |
| 文件(工具) | camelCase | formatDate.ts |
标准参考
查看详细模式:
/standards/global/naming-conventions.md
红色标志识别
| 标志 | 提问 |
|---|---|
| 单字母变量 | “d代表什么?” |
| 函数超过30行 | “我们能把它拆分成更小的函数吗?” |
| 嵌套超过3层 | “我们能使用提前返回吗?” |
| 复制粘贴代码 | “如果这个逻辑改变,需要更新多少地方?” |
| 注释掉代码 | “这是必要的吗?我们能删除它吗?” |
| 无跟踪的TODO | “有相关工单吗?” |
| 魔法字符串/数字 | “这应该是个命名常量吗?” |