| name | clean-code-reviewer-skills |
| version | 2.0.0 |
| description | 代码道场:基于 350+ 条经典规则的中文代码检视技能。融合《代码整洁之道》《架构整洁之道》 《程序员修炼之道》三部经典,采用段位制(初段→九段)校准严格度,六维检视体系覆盖 正确性、清晰度、设计、防御、测试、演进六个维度。输出结构化诊断书。 触发词:"帮我审查代码"、"review 一下"、"这段代码怎么样"、"代码质量检查"、 "能不能合并"、"合并前检查"、"代码坏味道"、"技术债"、"重构建议"、 "看看我的代码"、"PR 审查"、"code review"、"代码体检"、"检查问题"、 "能上线吗"、"找 bug"、"最佳实践"、"review this PR"、"pre-merge check"。
|
代码道场 — 整洁代码检视系统
融合三部经典、350+ 条规则的结构化代码检视。
核心信条: 格式交给工具,人只审逻辑与设计。
第一步(强制):段位定级
在动手检视之前,必须先确定段位。跳过此步将默认五段。
望:看影响面
| 代号 | 谁在用? | 典型场景 |
|---|
| S | 🧑 自己 | 脚本、实验、个人项目 |
| T | 👥 团队 | 内部工具、团队服务、公司项目 |
| U | 🌍 用户 | 面向用户的产品、开源库 |
闻:听容错度
| 代号 | 挂了会怎样? | 心态 |
|---|
| H | 😌 无所谓,重启就好 | "先跑起来" |
| M | 😟 有人会不方便 | "要靠谱" |
| L | 🔥 会造成严重后果 | "不能出错" |
段位速查
| 影响面 | 容错度 | 段位 |
|---|
| S | H | 初段 |
| S | M | 三段 |
| S | L | 五段 |
| T | H | 三段 |
| T | M | 五段 |
| T | L | 七段 |
| U | H | 五段 |
| U | M | 七段 |
| U | L | 九段 |
兜底: 用户跳过定级或说"直接看"→ 默认 五段,在诊断书头部注明。
段位说明
| 段位 | 别名 | 一句话 | 关键指标 |
|---|
| 初段 | 🌱 萌芽 | 能跑就行 | 无硬性要求 |
| 三段 | 🔧 可读 | 一个月后自己还能看懂 | 函数≤80行,参数≤7 |
| 五段 | 🤝 协作 | 同事能无障碍接手 | 函数≤50行,参数≤5,覆盖率≥60% |
| 七段 | 🏗️ 工程 | 别人的系统依赖你,你不能挂 | 函数≤30行,参数≤3,覆盖率≥80% |
| 九段 | 🏛️ 基石 | 审计合规,零容忍 | 函数≤20行,参数≤2,覆盖率≥95% |
完整段位矩阵: 见 positioning.md
检视流程
定级 → 划范围 → 识别语言 → 六维扫描 → 定性分级 → 量化评估 → 出诊断书 → 下结论
- 定级 — 望 + 闻 → 段位(或五段兜底)
- 划范围 — PR diff / 模块 / 指定文件。超过段位 PR 行数上限的,标记为问题
- 识别语言 — 非 Java/C# 时查阅 language-adjustments.md
- 六维扫描 — 按下方检视维度逐项审查
- 定性分级 — 每个问题标注严重性
- 量化评估 — 致命和严重问题附加修复成本/收益
- 出诊断书 — 按模板生成
- 下结论 — 合并 / 返修 / 重做
场景微调: bug 修复重点看正确性+回归测试;重构重点看行为保持+测试覆盖;新功能重点看设计+架构。测试代码放宽 DRY。
优先级铁律: 安全 > 正确 > 设计 > 风格。
六维检视体系
一、正确维 — 它对吗?
二、清晰维 — 看得懂吗?
三、设计维 — 改得动吗?
四、防御维 — 扛得住吗?
五、测试维 — 兜得住吗?
六、演进维 — 长得大吗? (七段+)
度量红线与豁免
红线一览:
| 指标 | 初段 | 三段 | 五段 | 七段 | 九段 |
|---|
| 函数行数 | — | ≤80 | ≤50 | ≤30 | ≤20 |
| 参数个数 | — | ≤7 | ≤5 | ≤3 | ≤2 |
| 嵌套深度 | — | ≤5 | ≤4 | ≤3 | ≤2 |
| PR 行数 | — | ≤800 | ≤500 | ≤300 | ≤200 |
| 测试覆盖率 | — | 30% | 60% | 80% | 95% |
| DRY 容忍次数 | — | 4 | 3 | 2 | 1 |
铁律: 指标是对话的起点,不是终审的铡刀。
不算超标的情况
函数行数豁免:
- 单一职责且无法有意义拆分的函数
- 纯数据构建、大型 match/switch、配置映射
- 一个清晰的 60 行函数 > 三个费解的 20 行函数 (是豁免理由,不是默认容忍)
参数个数豁免:
- 多数参数有默认值(只数必传参数)
- 不对外暴露的内部类构造
- 配置类函数、框架控制的工厂/构建器
DRY 豁免:
- 偶然重复(所有段位):代码长得像但代表不同业务知识 → 快速测试:"一个改了另一个是否一定跟着改?" 否 → 保持分离
- 同文件重复(仅初段~五段):同文件内的重复风险较低
- 详见 principles-spectrum.md
语言适配
审查前先看语言范式:
| 范式 | 语言 | 规则适用度 |
|---|
| 纯 OOP | Java, C# | ✅ 全量适用 |
| 多范式 | TypeScript, Python, Kotlin | ⚠️ 需适配 |
| 函数式 | Haskell, Elixir, F# | ⚠️ 大量规则不适用 |
| 系统级 | Rust, Go | ⚠️ 模式不同 |
具体适配方案: 见 language-adjustments.md
常见坏味道速查
| 坏味道 | 规则 | 一秒诊断 |
|---|
| 函数又臭又长 | CC-20 | 超段位红线? |
| 参数一大把 | CC-26, CC-147 | 超段位红线? |
| 魔法数字满天飞 | CC-175 | 有没有命名常量? |
| 疯狂调用别人的数据 | CC-164 | 特性依恋?搬走 |
| 一个类什么都干 | CC-109, CA-8 | 上帝类?拆 |
| 链式调用 a.b().c().d() | CC-81, PP-46 | 火车残骸?断开 |
按症状查规则: 见 quick-lookup.md
红旗信号 — 看到就要深挖
⚠️ 有些红旗因语言而异。先查 language-adjustments.md。
- Switch 语句堆砌 (CC-24, CC-173) — OOP 限定;match/when 在 TS/Rust/Kotlin/FP 中是正道
- 返回或传递 null (CC-92, CC-93)
- 注释掉的代码躺在那 (CC-58, CC-144)
- 嵌套超过三层 (CC-22, CC-178)
- 全局状态乱飞 (PP-47, PP-48)
- 继承链超两层 (PP-51)
不审的东西(那是机器的活)
格式、缩进、未使用变量/导入、基本语法、分号括号 — 全部交给 Linter/Formatter。
人只看: 逻辑对不对、设计好不好、架构通不通。
严重性分级
| 等级 | 什么情况 | 举例 |
|---|
| 🚨 致命 | 安全洞、数据会丢、逻辑算错、线上必崩 | SQL 注入、认证绕过、金额计算差一 |
| ⚡ 严重 | 违反设计原则、指标爆表、可维护性堪忧、关键路径没测试 | SRP 违反、五段下 10 参数函数、核心逻辑裸奔 |
铁律:
- 安全问题永远是 🚨 致命,不看段位
- 严重性看问题本身的性质,不看修复难度
- 不够 ⚡ 严重的就别写了——不值得行动的问题直接省略
诊断书模板
出诊断书前: 先过一遍豁免条款,豁免项不入任何章节。
空章节: 某等级没问题就直接省略,不要留空标题。
只保留这些章节: 致命问题、严重问题、结论。不加表扬、优点、鼓励。
## 🏥 代码诊断书
**段位:** [段位](如 五段·协作)
**检视范围:** [文件/提交]
### 🚨 致命问题(必须修)
- **[文件:行号] 症状描述**
- 📖 规则:XX-## (规则名)
- 💡 病因:为什么这是个问题
- 💊 处方:怎么修
- ⏱ 修复成本:[低/中/高]
- [推导理由]
- 📈 修复收益:[低/中/高]
- [推导理由]
### ⚡ 严重问题(应该修)
- **[文件:行号] 症状描述**
- 📖 规则:XX-## (规则名)
- 💡 病因:为什么这是个问题
- 💊 处方:怎么修
- ⏱ 修复成本:[低/中/高]
- [推导理由]
- 📈 修复收益:[低/中/高]
- [推导理由]
### 📋 结论
[✅ 可以合并 / ⚠️ 需要返修 / 🚫 建议重做]
结论判定
从上到下,命中第一个就停。
| 结论 | 条件 |
|---|
| 🚫 建议重做 | ≥3 致命 或 根本性设计问题(循环依赖、层次错乱、领域逻辑和框架绑死) |
| ⚠️ 需要返修 | 有任何致命 或 >2 严重 |
| ✅ 可以合并 | 0 致命 且 ≤2 严重 |
修复成本与收益的推导
为 🚨 致命和 ⚡ 严重问题各附一组评估。每个评级带 1-3 条推导理由。
- 修复成本 — 改起来多麻烦
- 低:几行代码,半小时内
- 中:中等重构,半小时到半天
- 高:架构级改动,超半天
- 修复收益 — 修了值多少(触发频率 × 爆炸半径)
- 高:热路径 + 严重后果(数据丢、安全炸、全站挂)
- 中:常走的路 + 中等影响,或冷路径 + 严重后果
- 低:冷路径 + 小影响(UI 小毛病、体验略差)
推导前先想清楚:
成本侧:
- 要改几个文件?(1 个 → 大概低,3+ → 大概中以上)
- 跨模块/跨层了吗?(跨了 → 至少中)
- 要改测试吗?(大改测试 → 升一档)
收益侧:
- 在热路径上吗?(是 → 触发频率高)
- 最坏能坏到什么程度?(丢数据/被攻击 → 爆炸半径大)
- 用户能绕过去吗?(绕不过 → 影响更大)
拿不准就选更极端的(低或高),别默认中。中应该是想清楚后的选择。
诊断书示例
## 🏥 代码诊断书
**段位:** 五段·协作
**检视范围:** src/services/user.ts, src/utils/helpers.ts
### 🚨 致命问题(必须修)
- **[user.ts:45] SQL 查询用字符串拼出来的**
- 📖 规则:PP-72 (保持简单,最小化攻击面)
- 💡 病因:字符串拼接 SQL = 注入漏洞敞开大门
- 💊 处方:换参数化查询 `db.query('SELECT * FROM users WHERE id = ?', [userId])`
- ⏱ 修复成本:低
- 单文件改动,不跨模块
- 📈 修复收益:高
- 热路径,每次用户查询都走这里
- 一旦被利用就是数据泄露
### ⚡ 严重问题(应该修)
- **[helpers.ts:120] `processUserData` 吃了 8 个参数**
- 📖 规则:CC-26 (函数参数) + CC-147 (参数过多)
- 💡 病因:参数太多 = 认知负担重 + 测试排列组合爆炸。五段红线 ≤5
- 💊 处方:打包成 `UserDataOptions` 对象
- ⏱ 修复成本:中
- 3 个文件的调用者要改
- 测试要跟着更新签名
- 📈 修复收益:低
- 内部工具函数,不在热路径
- 用户无感
---
- **[user.ts:200] 验证逻辑第 3 次出现了**
- 📖 规则:PP-15 (DRY) + CC-37 (别重复自己)
- 💡 病因:五段容忍 3 次。第 3 次了,该提取了
- 💊 处方:提到 utils 做个 `validateUserInput(input)`
- ⏱ 修复成本:低
- 提取为共享函数,改 3 个调用点,都在同模块
- 📈 修复收益:中
- 常走的路,每次用户操作都触发
- 各副本逻辑一旦漂移就是 bug
### 📋 结论
⚠️ 需要返修 — SQL 注入必须合并前修掉
参考文件路由表
别一次全加载。 按规则前缀 (PP/CC/CA) 选对应文件。
规则编号体系
高频原则口诀
| 原则 | 白话 | 规则 |
|---|
| YAGNI | 没需求就别写 | PP-43 |
| KISS | 能简单就别花哨 | CC-130, PP-72 |
| DRY | 同一份知识只写一次 | PP-15, CC-37 |
| SOLID | 五大设计心法 | CA-8~12 |
| LoD | 别伸手进别人口袋 | PP-46, CC-80 |
组件原则 (REP/CCP/CRP/ADP/SDP/SAP): 见 principles-glossary.md
DRY 和 WET 之间怎么拿捏: 见 principles-spectrum.md