code-refactoring

When to use this skill

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "code-refactoring" with this command: npx skills add supercent-io/skills-template/supercent-io-skills-template-code-refactoring

Code Refactoring

When to use this skill

  • Code review: Discovering complex or duplicated code

  • Before adding new features: Cleaning up existing code

  • After bug fixes: Removing root causes

  • Resolving technical debt: Regular refactoring

Instructions

Step 1: Extract Method

Before (long function):

function processOrder(order: Order) { // Validation if (!order.items || order.items.length === 0) { throw new Error('Order must have items'); } if (!order.customerId) { throw new Error('Order must have customer'); }

// Price calculation let total = 0; for (const item of order.items) { total += item.price * item.quantity; } const tax = total * 0.1; const shipping = total > 100 ? 0 : 10; const finalTotal = total + tax + shipping;

// Inventory check for (const item of order.items) { const product = await db.product.findUnique({ where: { id: item.productId } }); if (product.stock < item.quantity) { throw new Error(Insufficient stock for ${product.name}); } }

// Create order const newOrder = await db.order.create({ data: { customerId: order.customerId, items: order.items, total: finalTotal, status: 'pending' } });

return newOrder; }

After (method extraction):

async function processOrder(order: Order) { validateOrder(order); const total = calculateTotal(order); await checkInventory(order); return await createOrder(order, total); }

function validateOrder(order: Order) { if (!order.items || order.items.length === 0) { throw new Error('Order must have items'); } if (!order.customerId) { throw new Error('Order must have customer'); } }

function calculateTotal(order: Order): number { const subtotal = order.items.reduce((sum, item) => sum + item.price * item.quantity, 0); const tax = subtotal * 0.1; const shipping = subtotal > 100 ? 0 : 10; return subtotal + tax + shipping; }

async function checkInventory(order: Order) { for (const item of order.items) { const product = await db.product.findUnique({ where: { id: item.productId } }); if (product.stock < item.quantity) { throw new Error(Insufficient stock for ${product.name}); } } }

async function createOrder(order: Order, total: number) { return await db.order.create({ data: { customerId: order.customerId, items: order.items, total, status: 'pending' } }); }

Step 2: Remove Duplication

Before (duplication):

async function getActiveUsers() { return await db.user.findMany({ where: { status: 'active', deletedAt: null }, select: { id: true, name: true, email: true } }); }

async function getActivePremiumUsers() { return await db.user.findMany({ where: { status: 'active', deletedAt: null, plan: 'premium' }, select: { id: true, name: true, email: true } }); }

After (extract common logic):

type UserFilter = { plan?: string; };

async function getActiveUsers(filter: UserFilter = {}) { return await db.user.findMany({ where: { status: 'active', deletedAt: null, ...filter }, select: { id: true, name: true, email: true } }); }

// Usage const allActiveUsers = await getActiveUsers(); const premiumUsers = await getActiveUsers({ plan: 'premium' });

Step 3: Replace Conditional with Polymorphism

Before (long if-else):

class PaymentProcessor { process(payment: Payment) { if (payment.method === 'credit_card') { // Credit card processing const cardToken = this.tokenizeCard(payment.card); const charge = this.chargeCreditCard(cardToken, payment.amount); return charge; } else if (payment.method === 'paypal') { // PayPal processing const paypalOrder = this.createPayPalOrder(payment.amount); const approval = this.getPayPalApproval(paypalOrder); return approval; } else if (payment.method === 'bank_transfer') { // Bank transfer processing const transfer = this.initiateBankTransfer(payment.account, payment.amount); return transfer; } } }

After (polymorphism):

interface PaymentMethod { process(payment: Payment): Promise<PaymentResult>; }

class CreditCardPayment implements PaymentMethod { async process(payment: Payment): Promise<PaymentResult> { const cardToken = await this.tokenizeCard(payment.card); return await this.chargeCreditCard(cardToken, payment.amount); } }

class PayPalPayment implements PaymentMethod { async process(payment: Payment): Promise<PaymentResult> { const order = await this.createPayPalOrder(payment.amount); return await this.getPayPalApproval(order); } }

class BankTransferPayment implements PaymentMethod { async process(payment: Payment): Promise<PaymentResult> { return await this.initiateBankTransfer(payment.account, payment.amount); } }

class PaymentProcessor { private methods: Map<string, PaymentMethod> = new Map([ ['credit_card', new CreditCardPayment()], ['paypal', new PayPalPayment()], ['bank_transfer', new BankTransferPayment()] ]);

async process(payment: Payment): Promise<PaymentResult> { const method = this.methods.get(payment.method); if (!method) { throw new Error(Unknown payment method: ${payment.method}); } return await method.process(payment); } }

Step 4: Introduce Parameter Object

Before (many parameters):

function createUser( name: string, email: string, password: string, age: number, country: string, city: string, postalCode: string, phoneNumber: string ) { // ... }

After (grouped into object):

interface UserProfile { name: string; email: string; password: string; age: number; }

interface Address { country: string; city: string; postalCode: string; }

interface CreateUserParams { profile: UserProfile; address: Address; phoneNumber: string; }

function createUser(params: CreateUserParams) { const { profile, address, phoneNumber } = params; // ... }

// Usage createUser({ profile: { name: 'John', email: 'john@example.com', password: 'xxx', age: 30 }, address: { country: 'US', city: 'NYC', postalCode: '10001' }, phoneNumber: '+1234567890' });

Step 5: Apply SOLID Principles

Single Responsibility:

// ❌ Bad example: multiple responsibilities class User { constructor(public name: string, public email: string) {}

save() { // Save to DB }

sendEmail(subject: string, body: string) { // Send email }

generateReport() { // Generate report } }

// ✅ Good example: separated responsibilities class User { constructor(public name: string, public email: string) {} }

class UserRepository { save(user: User) { // Save to DB } }

class EmailService { send(to: string, subject: string, body: string) { // Send email } }

class UserReportGenerator { generate(user: User) { // Generate report } }

Output format

Refactoring Checklist

  • Function does one thing only (SRP)
  • Function name clearly describes what it does
  • Function is 20 lines or fewer (guideline)
  • 3 or fewer parameters
  • No duplicate code (DRY)
  • if nesting is 2 levels or fewer
  • No magic numbers (extract as constants)
  • Understandable without comments (self-documenting)

Constraints

Mandatory Rules (MUST)

  • Test first: Write tests before refactoring

  • Small steps: Change one thing at a time

  • Behavior preservation: No functional changes

Prohibited (MUST NOT)

  • Multiple tasks simultaneously: No refactoring + feature addition at the same time

  • Refactoring without tests: Risk of regression

Best practices

  • Boy Scout Rule: Leave code cleaner than you found it

  • Refactoring timing: Red-Green-Refactor (TDD)

  • Incremental improvement: Consistency over perfection

  • Behavior preservation: Refactoring involves no functional changes

  • Small commits: Commit in focused units

Behavior Validation (Code Simplifier Integration)

Step A: Understand Current Behavior

Fully understand current behavior before refactoring:

Behavior Analysis

Inputs

  • [list of input parameters]
  • [types and constraints]

Outputs

  • [return values]
  • [side effects]

Invariants

  • [conditions that must always be true]
  • [edge cases]

Dependencies

  • [external dependencies]
  • [state dependencies]

Step B: Validate After Refactoring

1. Run tests

npm test -- --coverage

2. Type check

npx tsc --noEmit

3. Lint check

npm run lint

4. Compare with previous behavior (snapshot tests)

npm test -- --updateSnapshot

Step C: Document Changes

Refactoring Summary

Changes Made

Behavior Preserved

  • Same input → same output
  • Same side effects
  • Same error handling

Risks & Follow-ups

  • [potential risks]
  • [follow-up tasks]

Test Status

  • Unit tests: passing
  • Integration tests: passing
  • E2E tests: passing

Troubleshooting

Issue: Tests fail after refactor

Cause: Behavior change occurred Solution: Revert and isolate the change, then retry

Issue: Code still complex

Cause: Multiple responsibilities mixed in one function Solution: Extract into smaller units with clear boundaries

Issue: Performance regression

Cause: Inefficient abstraction introduced Solution: Profile and optimize the hot path

Multi-Agent Workflow

Validation & Retrospectives

  • Round 1 (Orchestrator): Validate behavior preservation checklist

  • Round 2 (Analyst): Complexity and duplication analysis

  • Round 3 (Executor): Test or static analysis verification

Agent Roles

Agent Role

Claude Refactoring plan, code transformation

Gemini Large-scale codebase analysis, pattern detection

Codex Test execution, build verification

Workflow Example

1. Gemini: Codebase analysis

ask-gemini "@src/ extract list of high-complexity functions"

2. Claude: Refactoring plan and execution

Work based on IMPLEMENTATION_PLAN.md

3. Codex: Verification

codex-cli shell "npm test && npm run lint"

References

  • Refactoring (Martin Fowler)

  • Clean Code (Robert C. Martin)

  • SOLID Principles

Metadata

Version

  • Current Version: 1.0.0

  • Last Updated: 2025-01-01

  • Compatible Platforms: Claude, ChatGPT, Gemini

Related Skills

  • code-review

  • backend-testing

Tags

#refactoring #code-quality #DRY #SOLID #design-patterns #clean-code

Examples

Example 1: Basic usage

Example 2: Advanced usage

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

code-review

When to use this skill

Repository Source
Coding

codebase-search

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

agentic-development-principles

No summary provided by upstream source.

Repository SourceNeeds Review
code-refactoring | V50.AI