Guidelines
akash-network/node
Behavioral guidelines to reduce common LLM coding mistakes. An agent skill from akash-network/node.
Guides systematic code refactoring following the DRY (Don't Repeat Yourself) principle.
$ npx skills add YYH211/Claude-meta-skill --skill dry-refactoring -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install YYH211/Claude-meta-skill dry-refactoring --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/YYH211/Claude-meta-skill.git skills-src && mkdir -p .claude/skills && cp -r skills-src/dry-refactoring .claude/skills/dry-refactoring && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "dry-refactoring" agent skill from https://github.com/YYH211/Claude-meta-skill/tree/main/dry-refactoring into .claude/skills/dry-refactoring/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "dry-refactoring", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/YYH211/Claude-meta-skill/tree/main/dry-refactoringType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add YYH211/Claude-meta-skill --skill dry-refactoring -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install YYH211/Claude-meta-skill dry-refactoring --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/YYH211/Claude-meta-skill.git skills-src && mkdir -p .agents/skills && cp -r skills-src/dry-refactoring .agents/skills/dry-refactoring && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "dry-refactoring" agent skill from https://github.com/YYH211/Claude-meta-skill/tree/main/dry-refactoring into .agents/skills/dry-refactoring/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "dry-refactoring", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add YYH211/Claude-meta-skill --skill dry-refactoring -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install YYH211/Claude-meta-skill dry-refactoring --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/YYH211/Claude-meta-skill.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/dry-refactoring .cursor/skills/dry-refactoring && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "dry-refactoring" agent skill from https://github.com/YYH211/Claude-meta-skill/tree/main/dry-refactoring into .cursor/skills/dry-refactoring/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "dry-refactoring", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/YYH211/Claude-meta-skill.git --path dry-refactoring--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add YYH211/Claude-meta-skill --skill dry-refactoring -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install YYH211/Claude-meta-skill dry-refactoring --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/YYH211/Claude-meta-skill.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/dry-refactoring .gemini/skills/dry-refactoring && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "dry-refactoring" agent skill from https://github.com/YYH211/Claude-meta-skill/tree/main/dry-refactoring into .gemini/skills/dry-refactoring/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "dry-refactoring", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install YYH211/Claude-meta-skill dry-refactoringInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add YYH211/Claude-meta-skill --skill dry-refactoring -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/YYH211/Claude-meta-skill.git skills-src && mkdir -p .github/skills && cp -r skills-src/dry-refactoring .github/skills/dry-refactoring && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "dry-refactoring" agent skill from https://github.com/YYH211/Claude-meta-skill/tree/main/dry-refactoring into .github/skills/dry-refactoring/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "dry-refactoring", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add YYH211/Claude-meta-skill --skill dry-refactoring -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install YYH211/Claude-meta-skill dry-refactoring --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/YYH211/Claude-meta-skill.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/dry-refactoring .opencode/skills/dry-refactoring && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "dry-refactoring" agent skill from https://github.com/YYH211/Claude-meta-skill/tree/main/dry-refactoring into .opencode/skills/dry-refactoring/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "dry-refactoring", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
dry-refactoringGuides systematic code refactoring following the DRY (Don't Repeat Yourself) principle.
Dry Refactoring is an agent skill from YYH211/Claude-meta-skill. Guides systematic code refactoring following the DRY (Don't Repeat Yourself) principle. Use when user asks to eliminate code duplication, refactor repetitive code, apply DRY principle, or mentions code smells like copy-paste, magic numbers, or repeated logic. Implements a 4-step workflow from identifying repetition to verified refactoring.
Its SKILL.md is about 4.5k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Development, covering Refactoring. The repository describes itself as: A curated collection of reusable skills for Claude Code. Enhance Claude's capabilities with ready-to-use skill modules including comprehensive guides, templates, and best… The licence is MIT.
4 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit ba6f50c. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
gitpytestnpmFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md. Its commands use git and npm, which can reach the network depending on how they are called.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Dry Refactoring loads about 4.5k tokens when it runs. Until then it costs about 89 tokens; SKILL.md has 386 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from YYH211/Claude-meta-skill at commit ba6f50c, republished under its MIT licence (© YYH211). 386 words, ~4,541 tokens.
.claude/skills/dry-refactoring/SKILL.md (or your agent's skills folder).这个技能指导你系统性地应用 DRY (Don't Repeat Yourself) 原则,通过四步标准化流程消除代码重复,提升代码质量和可维护性。
使用此技能当用户请求:
关键触发词: DRY, 重复代码, 代码重复, 重构, 消除重复, 复制粘贴, 魔术数字, 代码坏味道, 抽象, 提取函数
系统中的每一处知识都必须拥有一个单一、明确、权威的表示。
这意味着:
两次法则 (Rule of Two): 当你第二次写下几乎相同的代码块时,警钟就应该敲响。这是开始重构的信号。
这是一个可在编码任何阶段应用的微循环。严格按照步骤执行,确保重构的安全性和有效性。
目标: 像侦探一样,对代码中的"坏味道"保持警惕,找出所有重复。
直接复制粘贴:
示例:
// 重复 1
function calculateOrderDiscount(orderTotal) {
if (orderTotal > 100) {
return orderTotal * 0.1;
}
return 0;
}
// 重复 2
function calculateCouponDiscount(couponTotal) {
if (couponTotal > 100) {
return couponTotal * 0.1;
}
return 0;
}"魔术数字"或字符串:
0.08、"http://api.example.com"、100示例:
# 魔术数字重复
def calculate_tax_1(amount):
return amount * 0.08 # ❌ 魔术数字
def calculate_tax_2(amount):
return amount * 0.08 # ❌ 再次出现
def calculate_total(amount):
tax = amount * 0.08 # ❌ 第三次
return amount + tax结构性重复:
示例:
// 结构性重复
function processUserData(user: User) {
if (user.age >= 18) {
user.status = 'adult';
} else {
user.status = 'minor';
}
}
function processProductData(product: Product) {
if (product.price >= 100) {
product.category = 'premium';
} else {
product.category = 'standard';
}
}逻辑重复:
示例:
// 逻辑重复:都在计算折扣,只是来源不同
function applyMembershipDiscount(price, memberLevel) {
const discountRates = { gold: 0.2, silver: 0.1, bronze: 0.05 };
return price * (1 - (discountRates[memberLevel] || 0));
}
function applySeasonalDiscount(price, season) {
const discountRates = { winter: 0.2, spring: 0.1, summer: 0.05 };
return price * (1 - (discountRates[season] || 0));
}当你审查代码时,检查以下信号:
💡 Action: 使用搜索功能查找重复的字面量、相似的函数名模式。记录所有重复出现的位置。
目标: 将重复的逻辑提取出来,封装到一个独立、可复用的单元中。
不变部分:
可变部分:
分析示例:
// 原始重复代码
const userEmail = validateEmail(user.email);
const adminEmail = validateEmail(admin.email);
const supportEmail = validateEmail(support.email);
// 分析:
// 不变部分:validateEmail() 调用
// 可变部分:不同的 email 值根据重复的特点,选择最合适的抽象方式:
| 抽象形式 | 适用场景 | 示例 |
|---|---|---|
| 函数 (Function) | 封装一段算法或行为 | 计算折扣、验证输入、格式化数据 |
| 类 (Class) | 封装行为 + 关联状态 | 用户管理器、数据处理器、配置管理器 |
| 模块/组件 | 一组相关的函数、类和配置 | 认证模块、日志模块、API 客户端 |
| 配置文件/常量 | 重复的魔术数字或字符串 | API 端点、税率、阈值 |
| 高阶函数 | 重复的控制流程或模式 | 重试逻辑、缓存包装、错误处理 |
函数抽象示例:
# ❌ 重复代码
def process_user_order(user_id, order_data):
user = db.query(User).filter_by(id=user_id).first()
if not user:
raise ValueError("User not found")
# 处理订单...
def process_user_payment(user_id, payment_data):
user = db.query(User).filter_by(id=user_id).first()
if not user:
raise ValueError("User not found")
# 处理支付...
# ✅ 抽象后
def get_user_or_error(user_id):
"""不变部分:获取用户并验证"""
user = db.query(User).filter_by(id=user_id).first()
if not user:
raise ValueError("User not found")
return user
def process_user_order(user_id, order_data):
user = get_user_or_error(user_id) # 可变部分:user_id
# 处理订单...
def process_user_payment(user_id, payment_data):
user = get_user_or_error(user_id) # 可变部分:user_id
# 处理支付...常量抽象示例:
// ❌ 魔术数字
function calculateTax(amount) {
return amount * 0.08;
}
function displayTaxInfo(amount) {
console.log(`Tax (8%): $${amount * 0.08}`);
}
// ✅ 抽象为常量
const TAX_RATE = 0.08;
function calculateTax(amount) {
return amount * TAX_RATE;
}
function displayTaxInfo(amount) {
console.log(`Tax (${TAX_RATE * 100}%): $${amount * TAX_RATE}`);
}类抽象示例:
// ❌ 重复的状态和行为
const userCache = new Map();
function getUserFromCache(id: string) { /*...*/ }
function setUserInCache(id: string, user: User) { /*...*/ }
const productCache = new Map();
function getProductFromCache(id: string) { /*...*/ }
function setProductInCache(id: string, product: Product) { /*...*/ }
// ✅ 抽象为类
class Cache<T> {
private store = new Map<string, T>();
get(id: string): T | undefined {
return this.store.get(id);
}
set(id: string, value: T): void {
this.store.set(id, value);
}
}
const userCache = new Cache<User>();
const productCache = new Cache<Product>();Do:
Don't:
💡 Action: 创建一个新的函数、类或配置文件,将"不变部分"放进去,将"可变部分"定义为参数。
目标: 用新的抽象单元替换所有旧的重复代码。
步骤:
替换示例:
Before (重复代码):
# 位置 1: user_service.py
def create_user(data):
if not data.get('email'):
return {'error': 'Email is required'}, 400
if not data.get('password'):
return {'error': 'Password is required'}, 400
# 创建用户...
# 位置 2: product_service.py
def create_product(data):
if not data.get('name'):
return {'error': 'Name is required'}, 400
if not data.get('price'):
return {'error': 'Price is required'}, 400
# 创建产品...After (使用抽象):
# 新抽象: validation_utils.py
def validate_required_fields(data, required_fields):
"""验证必填字段"""
for field in required_fields:
if not data.get(field):
return {'error': f'{field.capitalize()} is required'}, 400
return None
# 位置 1: user_service.py (已替换)
def create_user(data):
error = validate_required_fields(data, ['email', 'password'])
if error:
return error
# 创建用户...
# 位置 2: product_service.py (已替换)
def create_product(data):
error = validate_required_fields(data, ['name', 'price'])
if error:
return error
# 创建产品...有时候重复代码之间存在细微差异,需要特殊处理:
策略 1:添加可选参数
// 大部分重复,但有一个地方需要额外日志
function processData(data, options = {}) {
// 通用处理...
if (options.enableLogging) {
console.log('Processing:', data);
}
return result;
}
// 使用
processData(data1); // 无日志
processData(data2, { enableLogging: true }); // 有日志策略 2:回调函数
// 核心流程相同,但中间步骤不同
function processWithCustomStep<T>(
data: T,
customStep: (item: T) => T
): T {
// 前置处理
const prepared = prepare(data);
// 可变的自定义步骤
const processed = customStep(prepared);
// 后置处理
return finalize(processed);
}
// 使用
processWithCustomStep(userData, (user) => validateUser(user));
processWithCustomStep(productData, (product) => enrichProduct(product));策略 3:保留特殊情况
# 如果某个重复有本质上的不同,考虑保留它
def process_standard_order(order):
return apply_dry_abstraction(order, 'standard')
def process_vip_order(order):
# VIP 订单有完全不同的业务逻辑,不强行抽象
# 保留独立实现
pass⚠️ 警告: 如果只替换了一部分,你就创造了另一种不一致,情况可能更糟。确保全部替换或全部不替换。
💡 Action: 使用 IDE 的"查找所有引用"功能,确保没有遗漏任何重复点。
目标: 确保重构没有破坏任何功能,程序行为在重构前后完全一致。
为你新创建的抽象编写独立的单元测试:
测试覆盖要点:
示例:
# 抽象函数
def calculate_discount(price, discount_rate):
"""计算折扣后价格"""
if not 0 <= discount_rate <= 1:
raise ValueError("Discount rate must be between 0 and 1")
return price * (1 - discount_rate)
# 单元测试
def test_calculate_discount():
# 正常情况
assert calculate_discount(100, 0.1) == 90
assert calculate_discount(100, 0) == 100
# 边界情况
assert calculate_discount(0, 0.5) == 0
assert calculate_discount(100, 1) == 0
# 异常情况
with pytest.raises(ValueError):
calculate_discount(100, 1.5)
with pytest.raises(ValueError):
calculate_discount(100, -0.1)运行那些覆盖了被修改代码区域的集成测试:
# 运行特定模块的测试
pytest tests/test_user_service.py
pytest tests/test_product_service.py
# 或运行整个测试套件
npm test
pytest检查要点:
如果没有自动化测试(或测试覆盖不足),进行手动验证:
验证清单:
确保抽象没有引入性能问题:
import time
# 性能测试
def benchmark_function(func, *args, iterations=1000):
start = time.time()
for _ in range(iterations):
func(*args)
end = time.time()
return (end - start) / iterations
# 对比重构前后
old_time = benchmark_function(old_implementation, test_data)
new_time = benchmark_function(new_implementation, test_data)
print(f"Old: {old_time:.6f}s, New: {new_time:.6f}s")
print(f"Difference: {((new_time - old_time) / old_time * 100):.2f}%")如果在团队中工作,进行代码审查:
审查要点:
💡 Action: 运行所有相关测试,确保程序的外部行为在重构前后完全一致。没有测试?现在是编写测试的最佳时机。
// order_service.js
function calculateOrderTotal(order) {
let total = 0;
for (const item of order.items) {
total += item.price * item.quantity;
}
// 会员折扣
if (order.memberLevel === 'gold') {
total = total * 0.8; // ❌ 魔术数字
} else if (order.memberLevel === 'silver') {
total = total * 0.9; // ❌ 魔术数字
}
return total;
}
// cart_service.js
function calculateCartTotal(cart) {
let total = 0;
for (const item of cart.items) {
total += item.price * item.quantity; // ❌ 重复计算逻辑
}
// 优惠券折扣
if (cart.couponType === 'premium') {
total = total * 0.8; // ❌ 重复的折扣计算
} else if (cart.couponType === 'standard') {
total = total * 0.9; // ❌ 重复的折扣计算
}
return total;
}发现的重复:
0.8 和 0.9(明显重复)// pricing_utils.js (新建)
// 抽象 1:商品总价计算
function calculateItemsTotal(items) {
return items.reduce((total, item) => {
return total + (item.price * item.quantity);
}, 0);
}
// 抽象 2:折扣配置(消除魔术数字)
const DISCOUNT_RATES = {
membership: {
gold: 0.2, // 20% off
silver: 0.1, // 10% off
bronze: 0.05 // 5% off
},
coupon: {
premium: 0.2, // 20% off
standard: 0.1, // 10% off
basic: 0.05 // 5% off
}
};
// 抽象 3:应用折扣
function applyDiscount(amount, discountRate) {
if (discountRate < 0 || discountRate > 1) {
throw new Error('Invalid discount rate');
}
return amount * (1 - discountRate);
}
// 抽象 4:获取折扣率
function getDiscountRate(category, level) {
return DISCOUNT_RATES[category]?.[level] || 0;
}
export { calculateItemsTotal, applyDiscount, getDiscountRate };// order_service.js (重构后)
import { calculateItemsTotal, applyDiscount, getDiscountRate } from './pricing_utils.js';
function calculateOrderTotal(order) {
const subtotal = calculateItemsTotal(order.items);
const discountRate = getDiscountRate('membership', order.memberLevel);
return applyDiscount(subtotal, discountRate);
}
// cart_service.js (重构后)
import { calculateItemsTotal, applyDiscount, getDiscountRate } from './pricing_utils.js';
function calculateCartTotal(cart) {
const subtotal = calculateItemsTotal(cart.items);
const discountRate = getDiscountRate('coupon', cart.couponType);
return applyDiscount(subtotal, discountRate);
}// pricing_utils.test.js
import { calculateItemsTotal, applyDiscount, getDiscountRate } from './pricing_utils.js';
describe('Pricing Utils', () => {
describe('calculateItemsTotal', () => {
it('should calculate total for multiple items', () => {
const items = [
{ price: 10, quantity: 2 },
{ price: 5, quantity: 3 }
];
expect(calculateItemsTotal(items)).toBe(35);
});
it('should return 0 for empty items', () => {
expect(calculateItemsTotal([])).toBe(0);
});
});
describe('applyDiscount', () => {
it('should apply 20% discount correctly', () => {
expect(applyDiscount(100, 0.2)).toBe(80);
});
it('should throw error for invalid discount rate', () => {
expect(() => applyDiscount(100, 1.5)).toThrow('Invalid discount rate');
});
});
describe('getDiscountRate', () => {
it('should return correct membership discount', () => {
expect(getDiscountRate('membership', 'gold')).toBe(0.2);
});
it('should return 0 for unknown level', () => {
expect(getDiscountRate('membership', 'unknown')).toBe(0);
});
});
});
// 运行测试
// npm test pricing_utils.test.js重构成果:
DISCOUNT_RATES症状:创建了过于通用、难以理解的抽象。
示例:
// ❌ 过度抽象
function universalProcessor(data, options, callbacks, config, meta) {
// 100 行通用处理逻辑...
}
// ✅ 合理抽象
function processUserData(user) {
return validate(user) && transform(user);
}解决方案:
症状:只替换了部分重复点,留下了一些旧代码。
后果:
解决方案:
症状:抽象引入了不必要的性能开销。
示例:
# ❌ 每次调用都重新编译正则表达式
def validate_email(email):
return re.match(r'^[\w\.-]+@[\w\.-]+\.\w+$', email)
# ✅ 复用编译后的正则表达式
EMAIL_PATTERN = re.compile(r'^[\w\.-]+@[\w\.-]+\.\w+$')
def validate_email(email):
return EMAIL_PATTERN.match(email)解决方案:
症状:抽象暴露了过多内部实现细节。
示例:
// ❌ 暴露内部状态
class UserManager {
public users: Map<string, User>; // 直接暴露内部数据结构
getUser(id: string) {
return this.users.get(id);
}
}
// ✅ 隐藏内部实现
class UserManager {
private users: Map<string, User>;
getUser(id: string): User | undefined {
return this.users.get(id);
}
addUser(user: User): void {
this.users.set(user.id, user);
}
}解决方案:
不要试图一次性重构整个代码库:
策略:
示例工作流:
# 1. 创建特性分支
git checkout -b refactor/dry-pricing-logic
# 2. 重构一个模块
# 编辑 pricing_utils.js
# 3. 测试
npm test
# 4. 提交
git add pricing_utils.js
git commit -m "Extract pricing calculation to reusable utility"
# 5. 重构使用该模块的文件
# 编辑 order_service.js
# 6. 再次测试和提交
npm test
git add order_service.js
git commit -m "Refactor order service to use pricing utility"
# 7. 继续其他模块...好的抽象需要好的文档:
/**
* 计算商品折扣后的价格
*
* @param price - 原始价格(必须 >= 0)
* @param discountRate - 折扣率(0-1 之间,0.2 表示 20% 折扣)
* @returns 折扣后的价格
* @throws {Error} 如果 discountRate 不在有效范围内
*
* @example
* applyDiscount(100, 0.2) // 返回 80
* applyDiscount(50, 0) // 返回 50(无折扣)
*/
function applyDiscount(price: number, discountRate: number): number {
if (discountRate < 0 || discountRate > 1) {
throw new Error(`Invalid discount rate: ${discountRate}. Must be between 0 and 1.`);
}
return price * (1 - discountRate);
}利用类型系统防止误用:
// 使用类型别名增强可读性
type DiscountRate = number; // 0-1 之间
type Price = number; // >= 0
// 更好:使用品牌类型确保类型安全
type DiscountRate = number & { __brand: 'DiscountRate' };
function createDiscountRate(value: number): DiscountRate {
if (value < 0 || value > 1) {
throw new Error('Discount rate must be between 0 and 1');
}
return value as DiscountRate;
}
function applyDiscount(price: Price, discountRate: DiscountRate): Price {
return (price * (1 - discountRate)) as Price;
}
// 使用
const rate = createDiscountRate(0.2); // 类型检查通过
applyDiscount(100, rate);
// applyDiscount(100, 0.2); // ❌ 类型错误!必须使用 createDiscountRate如果没有测试,先写测试再重构:
// 步骤 1:为现有(重复的)代码写测试
describe('Original Implementation', () => {
it('should calculate order total correctly', () => {
const order = {
items: [{ price: 10, quantity: 2 }],
memberLevel: 'gold'
};
expect(calculateOrderTotal(order)).toBe(16); // 20 * 0.8
});
});
// 步骤 2:重构代码
// 步骤 3:确保测试仍然通过
// npm test在完成 DRY 重构后,验证以下内容:
DRY 原则是软件工程的基石之一。通过系统性地应用这个四步流程,你可以:
记住:
最终目标:
让每一处知识在系统中都有唯一的、权威的表示。当需要修改时,你只改一个地方,所有使用该知识的地方自动更新。
这就是 DRY 的力量。
© YYH211, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in dry-refactoring of YYH211/Claude-meta-skill.
Open the folder on GitHubat commit ba6f50c
We found 1 copy of this SKILL.md (exact, near-identical or edited) in other folders, from 1 other GitHub owner. This page covers the copy in YYH211/Claude-meta-skill, which our catalogue first saw on October 7, 2026.
Dry Refactoring next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Dry Refactoring this skillYYH211/Claude-meta-skill | 282 | 1 repos | ~4.5k | Automated safety check: Pass | MIT | |
| Guidelinesakash-network/node | 1.1k | 20 repos | ~577 | Automated safety check: Pass | MIT | |
| Component Refactoringlangflow-ai/langflow | 155k | — | ~3.5k | Automated safety check: Pass | MIT | |
| Migrate Core Code to Submodulestinyhumansai/openhuman | 42k | — | ~2.6k | Automated safety check: Pass | GPL-3.0 | |
| ast-grep Structural Searchcode-yeongyu/oh-my-openagent | 70k | — | ~3.3k | Automated safety check: Pass | MIT | |
| Systematic Code Refactoringluongnv89/claude-howto | 42k | — | ~3k | Automated safety check: Pass | MIT |
akash-network/node
Behavioral guidelines to reduce common LLM coding mistakes. An agent skill from akash-network/node.
langflow-ai/langflow
Refactor high-complexity React components in Langflow frontend.
tinyhumansai/openhuman
Plans and carries out moving non-host-specific code and its tests from the OpenHuman core into vendored tiny submodule libraries, then releases the submodule and re-pins the host.
code-yeongyu/oh-my-openagent
Searches and rewrites code by syntax-tree shape across 25 languages with ast-grep, for codemods, structural queries and YAML lint rules, using a Python wrapper script.
luongnv89/claude-howto
Guides refactoring in phases based on Martin Fowler's method: research, test coverage check, planning and small tested steps, with your approval at each phase.
skills-directory/skill-codex
A skill your agent uses when the user asks to run Codex CLI (codex exec, codex resume) or references OpenAI Codex for code analysis, refactoring, or automated editing
YYH211/Claude-meta-skill
根据真实代码仓库、官网页面、运行界面、模块范围和目标软著数量,分析软件著作权(软著)申报方向,拆分可申报主题,检查 Logo、版权、备案、截图和源码等材料约束,生成 3w-4w 字正文、局部代码片段、源码原文、网页截图证据和 .docx 文档。Use when Claude needs to prepare or split legitimate software copyright…
YYH211/Claude-meta-skill
Aggregates and summarizes the latest AI news from multiple sources including AI news websites and web search.
YYH211/Claude-meta-skill
Generates production-ready FastGPT workflow JSON from natural language requirements.
YYH211/Claude-meta-skill
Creates unique, production-grade frontend interfaces with exceptional design quality.
YYH211/Claude-meta-skill
Expert prompt engineering skill that transforms Claude into "Alpha-Prompt" - a master prompt engineer who collaboratively crafts high-quality prompts through flexible dialogue.
YYH211/Claude-meta-skill
Guides Claude in creating well-structured SKILL.md files following best practices.
Categories
Guides systematic code refactoring following the DRY (Don't Repeat Yourself) principle. Dry Refactoring is an agent skill from YYH211/Claude-meta-skill. Guides systematic code refactoring following the DRY (Don't Repeat Yourself) principle.
Dry Refactoring fits situations like: user asks to eliminate code duplication; refactor repetitive code; apply DRY principle; mentions code smells like copy-paste.
Run `npx skills add YYH211/Claude-meta-skill --skill dry-refactoring -a claude-code`. Or copy the skill folder (dry-refactoring in YYH211/Claude-meta-skill) into .claude/skills/dry-refactoring in your project. Claude Code loads it when a task matches its description.
Run `npx skills add YYH211/Claude-meta-skill --skill dry-refactoring -a codex`. Or copy the skill folder (dry-refactoring in YYH211/Claude-meta-skill) into .agents/skills/dry-refactoring in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add YYH211/Claude-meta-skill --skill dry-refactoring -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/dry-refactoring, .gemini/skills/dry-refactoring, .github/skills/dry-refactoring and .opencode/skills/dry-refactoring in your project.
Going by SKILL.md and its folder, Dry Refactoring needs the command-line tools its instructions call (git, pytest and npm). Our summary lists: Python 3.
SKILL.md contains no URLs. Its commands use git and npm, which can reach the network depending on how they are called. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Dry Refactoring is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 4.5k tokens (SKILL.md is roughly 18k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Dry Refactoring: Guidelines (akash-network/node, 1.1k stars), Component Refactoring (langflow-ai/langflow, 155k stars), Migrate Core Code to Submodules (tinyhumansai/openhuman, 42k stars) and ast-grep Structural Search (code-yeongyu/oh-my-openagent, 70k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
YYH211 (a GitHub user) maintains it in YYH211/Claude-meta-skill, which has 282 GitHub stars. The repository holds 8 skills in this directory. The repository was last updated on May 15, 2026.
Source: YYH211/Claude-meta-skill on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.