用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/fabioc-aloha/Alex_Plug_In --skill refactoring-patterns命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
正在显示 SKILL.md
基于 SOC 职业分类
| name | refactoring-patterns |
| description | Safe transformations — same behavior, better structure. |
| tier | core |
| applyTo | **/*refactor*,**/*extract*,**/*rename*,**/*inline* |
Safe transformations — same behavior, better structure.
Tests pass before AND after. Never refactor and add features in the same commit.
| Trigger | Action |
|---|---|
| Feature is hard to add | Refactor first, then add feature |
| Same bug twice | Refactor to prevent recurrence |
| "I don't understand" | Refactor for clarity |
| Duplicate code | Extract and reuse |
| Long function (>30 lines) | Extract logical units |
When a block does one logical thing, give it a name.
// Before
function processOrder(order: Order) {
// Validate order
if (!order.items.length) throw new Error('Empty order');
if (!order.customer) throw new Error('No customer');
if (order.total < 0) throw new Error('Invalid total');
// Calculate tax
const taxRate = order.region === 'EU' ? 0.20 : 0.10;
const tax = order.total * taxRate;
// Apply discount
const discount = order.customer.isPremium ? 0.15 : 0;
const finalTotal = order.total + tax - (order.total * discount);
return finalTotal;
}
// After
function processOrder(order: Order) {
validateOrder(order);
const tax = calculateTax(order);
const discount = calculateDiscount(order);
return order.total + tax - discount;
}
function validateOrder(order: Order): void {
if (!order.items.length) throw new Error('Empty order');
if (!order.customer) throw new Error('No customer');
if (order.total < 0) throw new Error('Invalid total');
}
function calculateTax(order: Order): number {
const taxRate = order.region === 'EU' ? 0.20 : 0.10;
return order.total * taxRate;
}
function calculateDiscount(order: Order): number {
return order.customer.isPremium ? order.total * 0.15 : 0;
}
Name complex expressions to reveal intent.
// Before
if (user.age >= 18 && user.country === 'US' && !user.banned && user.emailVerified) {
allowAccess();
}
// After
const isAdult = user.age >= 18;
const isUSResident = user.country === 'US';
const isInGoodStanding = !user.banned && user.emailVerified;
const canAccess = isAdult && isUSResident && isInGoodStanding;
if (canAccess) {
allowAccess();
}
Names should reveal what, not how.
// Before
const d = new Date().getTime() - start;
const arr = users.filter(u => u.a);
// After
const elapsedMs = new Date().getTime() - startTime;
const activeUsers = users.filter(user => user.isActive);
// Before
function calculatePay(employee: Employee): number {
switch (employee.type) {
case 'hourly':
return employee.hours * employee.rate;
case 'salaried':
return employee.salary / 12;
case 'commission':
return employee.sales * employee.commissionRate + employee.basePay;
}
}
// After
interface PayStrategy {
calculate(employee: Employee): number;
}
class HourlyPay implements PayStrategy {
calculate(emp: Employee): number {
return emp.hours * emp.rate;
}
}
class SalariedPay implements PayStrategy {
calculate(emp: Employee): number {
return emp. / ;
}
}
{
(: ): {
emp. * emp. + emp.;
}
}
// Before
function getPayAmount(employee: Employee): number {
let result: number;
if (employee.isSeparated) {
result = 0;
} else {
if (employee.isRetired) {
result = employee.pension;
} else {
result = employee.salary;
}
}
return result;
}
// After
function getPayAmount(employee: Employee): number {
if (employee.isSeparated) return 0;
if (employee.isRetired) return employee.pension;
return employee.salary;
}
| Smell | Symptoms | Refactoring |
|---|---|---|
| Long function | >30 lines, multiple comments explaining sections | Extract Function |
| Long parameter list | >4 parameters | Introduce Parameter Object |
| Duplicate code | Same logic in 2+ places | Extract Function, Pull Up Method |
| Feature envy | Method uses another object's data more than its own | Move Function |
| Large class | Class does too many things | Extract Class |
| Primitive obsession | Using primitives instead of small objects | Replace Primitive with Object |
| Data clumps | Same group of variables appear together | Introduce Parameter Object |
| Switch statements | Type-based conditionals | Replace Conditional with Polymorphism |
| Temporary field | Field only used sometimes | Extract Class |
| Refused bequest | Subclass ignores inherited methods | Replace Inheritance with Delegation |
| Refactor | Rewrite |
|---|---|
| Core design is sound | Fundamental design is wrong |
| Tests exist and pass | Code is untestable |
| <30% of code changes | >70% of code changes |
| Incremental improvement | Complete replacement |
| Low risk | Higher risk |
| Keep shipping features | Pause feature work |
1. Commit current state (safety net)
2. Run all tests (establish baseline)
3. Make ONE small change
4. Run tests
5. Commit with descriptive message
6. Repeat steps 3-5
Never: Refactor while adding features. Refactor OR feature, never both.
Most refactorings are automated in VS Code:
| Refactoring | VS Code Shortcut |
|---|---|
| Rename Symbol | F2 |
| Extract Function | Ctrl+Shift+R → Extract Function |
| Extract Variable | Ctrl+Shift+R → Extract Variable |
| Inline Variable | Ctrl+Shift+R → Inline Variable |
| Move to File | Ctrl+Shift+R → Move to new file |
Prefer IDE refactoring over manual edits — fewer mistakes, automatic reference updates.