用途
Boy Scout Rule 用于指导开发者在修改现有文件、重构、提升代码质量或接触遗留代码时,遵循“离开营地时比来时更干净”的原则,对代码进行小幅、渐进的改进。它不追求一次性完美重构,而是强调每次触碰文件都是一次改善机会,让代码质量随时间逐步累积提升。
主要能力
该规则明确了“可以改进什么”和“不应做什么”。
可改进的代码质量项包括:
- 删除死代码(注释块、未使用的函数)
- 修复所触碰文件中的 lint 问题
- 改善不清晰的命名(如 x、temp、data 改为描述性名称)
- 添加类型注解(TypeScript / Elixir @spec)
- 将魔法数字提取为具名常量
- 简化复杂逻辑
- 补充缺失的错误处理
- 更新过时的注释
- 修复格式
- 移除未使用的导入/变量
- 合并重复代码
不应做的事项包括:
- 大规模无关重构
- 无测试就改变行为
- 试图修复文件中的所有问题(应保持聚焦)
- 无测试的破坏性变更
- 过早优化
- 修改无关部分
使用方式
流程分为五步:
- 改动前:阅读文件,记录明显问题,运行 linter。
- 实施主要改动:实现功能或修复,编写测试。
- 应用改进:修复 lint、改善命名、添加类型、提取常量、删除死代码。
- 运行验证:例如
mix lint && mix test或yarn test:lint && yarn ts:check && yarn test。 - 记录:在提交信息中说明童子军式改进。
示例提交信息:
Add worker search filter
- Implement location-based filtering
- Add tests for search radius
Boy Scout improvements:
- Extract SEARCH_RADIUS constant
- Add type annotations to helper functions
- Remove unused import statements
- Improve variable naming in search logic
示例改进(前):
function calculateTotal(items) { // No types
let t = 0; // Poor naming
for (let i = 0; i < items.length; i++) { // Old-style
t += items[i].price * 1.08; // Magic number
}
return t;
}
示例改进(后):
const TAX_RATE = 1.08;
function calculateTotal(items: Item[]): number {
return items.reduce((total, item) => {
return total + (item.price * TAX_RATE);
}, 0);
}
改进点:类型、常量、命名、现代语法、简化。
适用场景
- 实现功能时:完成主要改动后顺手应用童子军改进,验证后一起提交。
- 代码审查时:寻找童子军改进机会,认可良好的童子军行为。
- 修复缺陷时:修复 bug,改善周边代码,补充测试,清理代码。
关键规则与限制
- 改进必须与主要改动放在同一提交中。
- 聚焦“爆炸半径”,即改动附近的代码。
- 优先可读性而非炫技。
- 改进后始终运行完整测试套件。
- 对业务逻辑不确定时,应寻求帮助。
- 小幅改进优于完美重构。
检查清单
- 删除所触碰文件中的死代码
- 修复 lint 问题
- 在改动处改善命名
- 补充缺失的类型注解
- 提取魔法数字
- 更新过时注释
- 移除未使用导入
- 简化复杂逻辑
- 添加错误处理
- 所有测试通过
- 无新增 lint 错误
- 在提交信息中记录
核心理念
渐进改进,而非追求完美;小幅改进随时间复利;每个触碰的文件都是机会;做代码库的好管家;对较大改进有疑问时,请求审查。