mcpField
D
dont-repeat-yourself

dont-repeat-yourself

github.com/yanko-belov开发1395 次安装40 周前更新
代码仓库

关于 dont-repeat-yourself

dont-repeat-yourself 是一项面向开发者的编码技能,指导将每段逻辑或知识集中在一个位置。它着重识别复制粘贴模式,并通过参数化差异来提取共用代码。

主要功能

  1. 01识别重复代码和逻辑
  2. 02提取共用函数与验证器
  3. 03参数化相似代码中的差异
  4. 04集中管理重复常量和规则
  5. 05利用重复迹象指导重构

适用场景

  1. 01避免为新功能复制现有代码
  2. 02合并多个表单中的重复验证
  3. 03修复分散在多个文件中的计算逻辑
  4. 04重构略有差异的相似函数

安装

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

$npx skills add https://github.com/yanko-belov/code-craft --skill dont-repeat-yourself

安装后在 Claude Code 中输入/dont-repeat-yourself确认已加载。

详细介绍

DRY(不要重复自己)

概述

系统中的每一条知识都必须只有一种明确无歧义的表示方式。

如果你发现自己要把同一段逻辑写两遍,就把它提取出来。重复代码是随时可能引发问题的隐患。

适用场景

  • 编写与现有代码相似的代码
  • 复制粘贴后再修改
  • 在多个文件中进行相同的修改
  • 在多个表单中重复编写验证逻辑
  • 在不同位置进行相同的计算

铁律

NEVER duplicate logic. Extract and reuse.

没有例外:

  • 不能因为“复制更快”而例外
  • 不能因为“它们有一点不同”而例外
  • 不能因为“我之后会重构”而例外
  • 不能因为“只有几行”而例外

检测:复制粘贴的异味

如果你正准备复制并修改代码,请停下来:

// ❌ VIOLATION: Duplicated validation
function validateRegistrationEmail(email: string): boolean {
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}

function validateProfileEmail(email: string): boolean {
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email); // Same logic!
}

// ✅ CORRECT: Single source of truth
function validateEmail(email: string): boolean {
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}

// Reuse everywhere
const isValidRegistration = validateEmail(regEmail);
const isValidProfile = validateEmail(profileEmail);

检测:“需要在多个地方修改”测试

如果修复一个错误需要修改多个位置,那就说明存在重复:

// ❌ Bug in tax calculation requires changes in 3 files
// cart.ts:      const tax = price * 0.08;
// checkout.ts:  const tax = price * 0.08;
// invoice.ts:   const tax = price * 0.08;

// ✅ Single source of truth
// tax.ts:       export const calculateTax = (price: number) => price * TAX_RATE;

正确做法:提取并参数化

当代码“几乎相同”时,提取共同部分,并将差异参数化:

// ❌ VIOLATION: Similar functions with minor differences
function formatUserName(user: User): string {
  return `${user.firstName} ${user.lastName}`;
}

function formatAdminName(admin: Admin): string {
  return `${admin.firstName} ${admin.lastName} (Admin)`;
}

// ✅ CORRECT: Parameterized
function formatName(person: { firstName: string; lastName: string }, suffix?: string): string {
  const name = `${person.firstName} ${person.lastName}`;
  return suffix ? `${name} (${suffix})` : name;
}

抵御压力的应对方案

1. “复制更快”

压力:“我就复制这段代码,再改一改”

**回应:**复制会产生两个需要维护的地方。两处代码会逐渐产生差异,进而引发错误。

**行动:**先提取共享逻辑,再在两个地方使用它。

2. “它们有一点不同”

压力:“这些函数几乎一样,但又不完全相同”

回应:“几乎相同”=提取共同部分,并将差异参数化。

**行动:**找出共用部分,将其提取出来,并把差异设为参数。

3. “只有几行”

压力:“只有 3 行,不值得提取”

**回应:**重复 5 次的 3 行代码=15 行需要维护。错误也会不断增加。

**行动:**即使只有少量重复,也要提取出来,并起个好名字。

4. “我之后会重构”

压力:“先发布,之后再整理成 DRY”

**回应:**你不会这么做。重复会不断蔓延。现在整理成 DRY 只需 2 分钟。

**行动:**在提交重复代码之前先提取。

危险信号——停下来重新考虑

如果你注意到以下任意情况,就说明你即将违反 DRY:

  • 工作流中出现 Ctrl+C / Ctrl+V
  • “这个和那个函数很像”
  • 多处出现相同的正则表达式或验证逻辑
  • 重复出现相同的错误处理模式
  • 重复相同的数据转换逻辑
  • 在多个文件中定义常量

以上情况都意味着:提取到共享位置。

重复的类型

类型示例解决方案
代码相同的函数体出现两次提取函数
逻辑相同的算法,不同的名称提取并参数化
数据多个文件中出现相同的常量将常量集中管理
结构重复出现相同形态的类提取接口或基类
知识多处出现业务规则建立唯一可信来源

快速参考

症状行动
复制粘贴代码提取共享函数
相同的验证逻辑出现两次创建验证器模块
多个文件中出现相同的常量创建常量文件
相似的函数提取并参数化
修复错误需要多处修改合并到一个位置

常见的自我辩解(均不成立)

借口事实
“复制更快”维护重复代码更慢。
“它们有一点不同”提取共同部分,并将差异参数化。
“只有几行”几行代码 × 多个位置=许多错误。
“我之后会重构”你不会这么做。现在就提取。
“上下文不同”逻辑相同,代码就应相同,与上下文无关。
“复制出来更易读”命名并提取后的函数更易读。

归根结底

一条知识。在代码中只出现一个地方。

编写相似代码时:停下来,查找已有代码,必要时提取并复用。重复是维护噩梦的根源。

评论

支持 Markdown