mcpField
C
clean-code

clean-code

github.com/marcioaltoe开发055 次安装今天更新
代码仓库

关于 clean-code

面向开发者的整洁代码参考技能,适用于编写、审查和重构代码。内容围绕可读性与可维护性,提供原则、代码异味识别及提交前检查。

主要功能

  1. 01命名与函数设计
  2. 02识别代码异味
  3. 03格式与错误处理
  4. 04注释编写指引
  5. 05面向对象练习
  6. 06提交前检查清单

适用场景

  1. 01选择清晰的名称和函数结构
  2. 02审查代码以改善可维护性
  3. 03重构旧代码并降低复杂度

安装

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

$npx skills add https://github.com/marcioaltoe/skills --skill clean-code

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

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

agents/
openai.yaml
references/
CODE_SMELLS.md
NAMING.md
OBJECT_CALISTHENICS.md

详细介绍

清晰代码

将“能运行的代码”转变为“清晰代码”的原则——让任何开发者都能阅读、理解并改进代码。

“如果团队中的每个人都能轻松理解代码,那么代码就是清晰的。”——Dave Thomas

适用场景

在以下场景中参考这些指南:

  • 编写新代码并选择名称、函数签名和结构
  • 审查拉取请求,检查可读性和可维护性
  • 重构遗留代码或降低复杂度
  • 识别并修复代码异味
  • 改进团队代码规范

规则类别

优先级类别影响
1命名高 — 影响每一行代码
2函数高 — 抽象的核心单元
3代码异味高 — 尽早发现可防止代码腐化
4格式中 — 让代码一目了然
5错误处理中 — 提高健壮性和清晰度
6注释中 — 大多数注释都可以避免
7对象柔术进阶目标 — 改进面向对象设计的练习

1. 命名

好的名称是提升可读性最有效的方法。

优先顺序:

  1. 一致性 — 同一概念在任何地方都使用同一名称
  2. 揭示意图 — 名称说明它做什么,而不是怎么做
  3. 具体明确 — 避免使用 data、info、manager、handler、utils 等含糊的名称
  4. 便于搜索 — 名称要足够独特,方便使用 grep 搜索
  5. 简洁 — 简短但不晦涩
// Bad
const d = new Date();
const arr = users.filter((u) => u.a);
function process(data: any) {}

// Good
const createdAt = new Date();
const activeUsers = users.filter((user) => user.isActive);
function validatePayment(payment: Payment) {}

命名约定:

  • 类/类型:使用名词(Customer、OrderRepository)。避免使用 Manager、Data、Info。
  • 方法/函数:使用动词(createOrder、validateEmail、isEligible)
  • 布尔值:使用疑问形式(isActive、hasPermission、canWithdraw)
  • 集合:使用复数名词(users、orderItems)

完整指南请参阅 references/NAMING.md。

2. 函数

// Bad — does too many things, unclear name
function handle(order: Order, sendEmail: boolean, log: boolean) {
  // validate, calculate, save, email, log — all in one
}

// Good — small, single-purpose, descriptive
function validateOrder(order: Order): ValidationResult { ... }
function calculateTotal(items: OrderItem[]): Money { ... }
function saveOrder(order: Order): Promise<void> { ... }

规则:

  • 简短 — 尽量控制在 20 行以内
  • 只做一件事 — 如果需要用“并且”来描述它,就将其拆分
  • 单一抽象层级 — 不要混合业务逻辑与底层细节
  • 参数尽量少 — 理想情况下为 0 至 2 个,3 个及以上时应考虑使用参数对象
  • 没有副作用 — 或在名称中明确体现(使用 saveAndNotify,而不是 save)
  • 命令/查询分离 — 函数要么执行操作,要么返回结果,不能两者兼顾

3. 代码异味

表明代码可能需要重构的迹象。它们不是 bug,而是设计上的阻碍。

异味症状快速修复
过长方法超过 20 行,包含多个关注点提取方法
过大类职责过多提取类(SRP)
参数列表过长参数超过 3 个引入参数对象
基本类型偏执使用字符串/数字表示领域概念封装为值对象
依恋情结方法使用其他类的数据多于自身数据移动方法
数据泥团同一组字段总是一起出现提取类
Switch 语句在代码库中使用 switch/if-else 检查类型用多态替代
发散式变化一个类因多种原因而修改按职责拆分
霰弹式修改一项修改影响多个文件将相关代码集中在一起
投机性通用化“以防万一”而添加的抽象删除(YAGNI)
死代码无法到达或未使用的代码删除
消息链a.getB().getC().doSomething()隐藏委托(迪米特法则)

详细示例和重构策略请参阅 references/CODE_SMELLS.md。

4. 格式

报纸隐喻 — 代码应像报纸文章一样从上到下阅读。顶部先给出高层摘要,下面再呈现细节。

class OrderProcessor {
  // Public API first — the "headline"
  process(order: Order): ProcessResult {
    this.validate(order);
    const total = this.calculateTotal(order);
    return this.save(order, total);
  }

  // Supporting methods below, in order of appearance
  private validate(order: Order) { ... }
  private calculateTotal(order: Order): Money { ... }
  private save(order: Order, total: Money): ProcessResult { ... }
}

规则:

  • 相关代码应放在一起(垂直紧凑)
  • 不同概念之间留空行(垂直疏朗)
  • 变量应在靠近其使用位置的地方声明
  • 调用方放在被调用方上方(逐步下降规则)
  • 缩进保持一致 — 不容妥协

5. 错误处理

  • 优先使用异常,而非错误代码 — 让正常流程保持简洁
  • 不要返回 null — 使用 undefined、Result 类型或抛出异常
  • 不要传入 null — 否则到处都需要防御性检查
  • 尽早失败 — 在边界处验证,信任内部代码
  • 使用具体的异常 — 优先使用 InsufficientFundsError,而非通用的 Error
// Bad — null checks cascade through codebase
function getUser(id: string): User | null {
  return db.find(id);
}
const user = getUser(id);
if (user === null) { ... } // Every caller must check

// Good — throw at boundary, trust within domain
function getUser(id: string): User {
  const user = db.find(id);
  if (!user) throw new UserNotFoundError(id);
  return user;
}

6. 注释

“不要注释糟糕的代码——重写它。”

大多数注释都是为了弥补代码未能表达意图。应优先编写自解释的代码,而非添加注释。

好的注释:

  • 解释为什么要这样做(业务原因、非显而易见的决策)
  • 警告(“由于 X,这段代码运行缓慢”“这里的顺序很重要”)
  • 附带上下文的 TODO(链接到问题)
  • 法律/许可证声明
  • 公共 API 文档(库的 JSDoc)

不好的注释:

  • 复述代码的作用(// increment counter)
  • 注释掉的代码(这正是 git 的用途)
  • 日志/变更记录注释
  • 无意义内容(// constructor、// getters)
  • 强制要求的样板内容
// Bad — restates the obvious
// Check if user is active
if (user.isActive) { ... }

// Good — explains a non-obvious business rule
// Users who haven't verified email within 30 days are auto-deactivated
// per compliance requirement GDPR-2024-42
if (user.isAutoDeactivated) { ... }

7. 对象体操

Jeff Bay 提出的九项练习,用于改进面向对象设计。将其视为理想目标——练习时严格遵守,在生产环境中灵活运用。

#规则目标
1每个方法最多一层缩进积极拆分方法
2不要使用 else尽早返回、使用守卫子句和多态
3为所有具有领域含义的基本类型添加封装使用值对象(Email、Money、UserId)
4使用一等集合用领域专用类封装数组
5每行只出现一个点遵循迪米特法则——只与熟悉的对象交互
6不要使用缩写如果名称太长,说明类承担了太多职责
7保持实体精简类少于 50 行,方法少于 10 行
8限制实例变量数量力求控制在 2–3 个;这会促使类职责聚焦
9不使用 getter/setter对象应有行为,而不只是数据

每条规则的示例请参阅 references/OBJECT_CALISTHENICS.md。

实现检查清单

提交代码前:

  • 新团队成员能否在不提问的情况下理解这段代码?
  • 名称是否清晰表达意图且保持一致?
  • 每个函数是否只做一件事?
  • 是否有我可以顺手修复的代码异味?
  • 注释是否解释了为什么,而不是做什么?
  • 错误处理是否简洁且具体?
  • 我是否让代码比接手时更好?(童子军规则)

评论

支持 Markdown