mcpField
C
clean-code

clean-code

github.com/pixel-process-ug开发390 次安装33 周前更新
代码仓库

关于 clean-code

用于分析、重构和维护软件的 clean-code 技能。它引导开发者评估代码异味,并运用 SOLID 原则、命名规范、错误处理和复杂度管理。

主要功能

  1. 01分析代码上下文与复杂度
  2. 02识别并确定代码异味优先级
  3. 03逐步执行重构
  4. 04运用 SOLID 和 DRY 原则
  5. 05指导命名与错误处理

适用场景

  1. 01重构前评估代码库
  2. 02规划减少代码异味的修改
  3. 03提升可读性和可测试性
  4. 04重构时保持程序行为

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/pixel-process-ug/superkit-agents --skill clean-code

安装后在 Claude Code 中输入/clean-code确认已加载。

详细介绍

清洁代码

概述

运用清洁代码原则,打造可读、可维护、可测试的软件。本技能涵盖 SOLID 原则、DRY 实践、代码异味识别、重构模式、命名规范、错误处理和复杂度管理。基于 Robert C. Martin、Martin Fowler 和 Kent Beck 的著作。

开始时宣布:“我正在使用 clean-code 技能来提升代码质量。”


阶段 1:分析当前代码

目标: 在修改任何内容之前,结合完整上下文阅读并理解代码。

操作
  1. 在完整上下文中阅读代码(而不只是代码片段)
  2. 明确代码的职责和用途
  3. 衡量圈复杂度
  4. 梳理耦合关系和依赖项
  5. 记录现有测试
停止——在进入阶段 2 之前,必须满足:
  • 已在完整上下文中阅读代码
  • 已理解代码的用途和职责
  • 已识别复杂度热点
  • 已了解现有测试覆盖情况

阶段 2:识别代码异味

目标: 使用下方参考表,列出所有代码异味。

膨胀症
异味检测方式重构方法
过长方法> 30 行提取方法
过大类> 300 行或 > 5 项职责提取类
参数列表过长> 3 个参数引入参数对象
数据泥团相同参数总是一起出现提取类
基本类型偏执使用基本类型,而不是小型对象替换为值对象
面向对象滥用者
异味检测方式重构方法
Switch 语句根据类型进行 Switch 判断替换为多态
平行继承体系每个子类都需要对应的平行子类合并层次结构
被拒绝的遗赠子类忽略继承的方法用委托替换继承
变更阻碍因素
异味检测方式重构方法
发散式变化一个类因多种原因而修改提取类(SRP)
散弹式修改一项更改影响多个类移动方法、内联类
可有可无项
异味检测方式重构方法
死代码无法到达或未使用删除
投机性通用性“以防万一”而创建的未使用抽象收起层次结构、删除
解释糟糕代码的注释注释在弥补代码表达不清的问题重命名、提取方法
停止——在进入阶段 3 之前,必须满足:
  • 已列出所有代码异味
  • 已为每个异味确定优先级(高/中/低)
  • 已为每个异味确定重构方法

阶段 3:执行重构

目标: 一次应用一种重构模式,并在每次之后验证测试。

操作
  1. 每次只应用一种重构
  2. 每次更改后运行测试
  3. 如果任何测试失败,立即回滚
  4. 持续进行,直到代码整洁
  5. 检查命名、结构和文档
停止——满足以下条件时,重构完成:
  • 所有高优先级异味都已解决
  • 每次更改后,所有测试均通过
  • 重构期间未更改任何行为
  • 新团队成员能够读懂代码

SOLID 原则

S — 单一职责原则

一个类/模块应该有且只有一个变更理由。

异味: 一个类因多种无关原因而修改。
修复: 将不同职责提取到独立的类中。

O — 开闭原则

对扩展开放,对修改关闭。

异味: Switch 语句随着新类型的增加而不断增长。
修复: 使用多态、策略模式或插件架构。

L — 里氏替换原则

子类型必须能够替换其基类型。

异味: 子类重写方法并抛出“not supported”。
修复: 重构层次结构;优先使用组合而非继承。

I — 接口隔离原则

客户端不应依赖它不使用的方法。

异味: 接口包含许多方法;实现者会将一些方法留空。 修复: 将接口拆分为更小、更专注的接口。

D — 依赖倒置原则

依赖抽象,而非具体实现。

异味: 高层模块直接导入低层模块。 修复: 通过接口/抽象类注入依赖。


命名约定

规则
元素约定示例
变量用描述其所保存内容的名词命名userCount,而不是 n
布尔值以 is/has/can/should 为前缀isActive、hasPermission
函数用描述其作用的动词命名calculateTotal、fetchUsers
常量UPPER_SNAKE_CASEMAX_RETRY_COUNT
类使用 PascalCase 名词UserRepository、PaymentService
接口描述能力Serializable、Cacheable
名称长度指南
作用域长度示例
循环计数器1-2 个字符i、j(仅限极小循环)
Lambda 参数上下文明确时使用 1-3 个字符users.filter(u => u.active)
局部变量简短但具有描述性total、result
函数名称中等长度,具有描述性calculateMonthlyRevenue
类名称按需命名AuthenticationTokenValidator

函数指南

大小和结构
  • 函数应只做一件事
  • 理想长度:5-15 行(不包括样板代码)
  • 最长:30 行(超过此长度时应拆分)
  • 参数最多:3 个(超过此数量时使用选项对象)
守卫子句(提前返回)
// Bad: nested conditions
function getDiscount(user) {
  if (user) {
    if (user.isPremium) {
      if (user.orderCount > 10) {
        return 0.2;
      }
    }
  }
  return 0;
}

// Good: guard clauses
function getDiscount(user) {
  if (!user) return 0;
  if (!user.isPremium) return 0;
  if (user.orderCount <= 10) return 0;
  return 0.2;
}

错误处理模式

决策表
方法适用场景示例
Result 类型函数式风格、预期内的失败Result<T, E> 返回类型
特定异常面向对象风格、异常情况throw new ValidationError(...)
错误代码C 风格 API、跨语言场景返回代码 + 消息
Option/Maybe值可能存在,也可能不存在Option<User>
Result 类型模式
type Result<T, E = Error> =
  | { success: true; data: T }
  | { success: false; error: E };

function parseConfig(raw: string): Result<Config, ParseError> {
  try {
    const config = JSON.parse(raw);
    if (!isValidConfig(config)) {
      return { success: false, error: new ParseError('Invalid config structure') };
    }
    return { success: true, data: config };
  } catch {
    return { success: false, error: new ParseError('Invalid JSON') };
  }
}
错误处理禁忌清单
  • 切勿捕获并悄无声息地忽略错误
  • 切勿将异常用于控制流
  • 切勿用 null 表示错误
  • 切勿在记录错误后重新抛出,却不补充上下文

复杂度指标

范围风险级别操作
1-5低无需操作
6-10中等考虑重构
11-20高应进行重构
21+严重必须重构
降低复杂度
  1. 将复杂条件提取为命名布尔值
  2. 使用守卫子句替代嵌套条件语句
  3. 使用多态替代类型检查
  4. 拆分为更小的函数
  5. 使用查找表替代 switch/if 链

DRY 应用决策表

情况是否应用 DRY?理由
逻辑完全重复是相同逻辑应只在一处实现
出现三次或更多是三次原则验证了这一模式
仅出现两次等一等可能只是偶然相似
结构相似,但用途不同否变更原因不同
抽象会增加更多复杂度否清晰度优先于 DRY

注释理念

好的注释
类型示例
原因(推理过程)// 使用二分查找,因为列表已排序且项目数超过 10K
法律声明版权、许可证头部
附带工单的 TODO// TODO(PROJ-123): 添加速率限制
警告// WARNING: 这不是线程安全的
公共 API 文档公共接口的 JSDoc/TSDoc
不好的注释(删除注释,改为修正代码)
类型示例
复述代码在 counter++ 前写 // 增加计数器
已注释掉的代码改用版本控制
日志式注释改用 git log
闭合大括号注释} // end if

反模式/常见错误

反模式错误原因正确做法
过早抽象将意图不同的代码强行 DRY 化等到符合三次原则时再处理
上帝类什么都知道,什么都做按职责拆分(SRP)
特性嫉妒方法使用其他类的数据多于自身数据将方法移至数据所属的类
字符串类型数据应使用枚举/类型的地方却使用字符串定义合适的类型
魔法数字含义不明确,容易出错使用具名常量
布尔陷阱函数使用会改变行为的布尔参数使用具名选项或拆分为多个函数
过度设计为不存在的问题创建抽象YAGNI——你不会需要它

集成点

技能关系
code-review代码审查会识别代码异味,供 clean-code 处理
test-driven-developmentTDD 可确保重构过程中保留行为
senior-frontend前端组件遵循整洁代码原则
senior-backend后端服务遵循 SOLID 和整洁架构
performance-optimization整洁代码有助于更轻松地进行性能优化
systematic-debugging整洁代码更易于调试

不可变性偏好

  • 默认使用 const(JavaScript/TypeScript)
  • 使用 readonly 属性和 ReadonlyArray
  • 优先使用展开/解构,而不是变更数据
  • 对状态使用不可变更新模式
  • 只有性能分析表明有必要时才进行变更

技能类型

灵活——根据上下文应用原则。并非每个函数都需要只有 5 行;也并非每种模式都需要符合 SOLID。运用判断,以团队易读性为先,而非追求理论上的纯粹。

评论

支持 Markdown