dry-refactor

SKILL.md

DRY Refactoring

Process

  1. Identify - Exact copies, similar patterns, parallel hierarchies, naming patterns (data1/data2, handleXClick)
  2. Analyze - Coupling, cohesion, frequency (Rule of Three: wait for 3+ occurrences), volatility
  3. Refactor - Choose technique below, extract incrementally, test after each step

Techniques

Extract Function - Same logic in multiple places

getFullName(user: User) => `${user.firstName} ${user.lastName}`

Extract Variable - Repeated expression

const isWorkingAge = user.age >= 18 && user.age < 65;

Parameterize - Code differs only in values

validateField(value: string, pattern: RegExp)
// Use: validateField(email, EMAIL_REGEX)

Extract Class - Related functions scattered

class UserRewards {
  calculateDiscount(user, amount) { }
  getLoyaltyPoints(user) { }
}

Polymorphism - Repeated switch/if-else

interface PaymentProcessor { process(amount: number): void }
class CreditProcessor implements PaymentProcessor { }

Strategy Pattern - Duplicated algorithm selection

const strategies = { date: byDate, name: byName };
items.sort(strategies[sortType] ?? byPriority);

Pull Up Method - Identical methods in subclasses

class BaseUser { getDisplayName() { } }
class AdminUser extends BaseUser { }

Detection

Code Smells: Look for numbered variables (data1, data2), parallel function names (handleXClick), near-identical code differing only in constants, repeated validation/error handling, parallel class structures, large switches in multiple places, repeated null checks, magic numbers

Rule of Three: Wait for 3+ occurrences before abstracting

When NOT to DRY

  • Coincidental similarity - Avoid abstracting different domains/business rules that happen to look alike (will diverge)
  • Premature abstraction - Wait until pattern is clear; early abstraction often guesses wrong
  • Single use - Skip abstraction when code appears 1-2 times and is unlikely to grow
  • Test clarity - Prefer readable test setup over DRY
  • Over-engineering - Avoid abstracting every 2-3 line similarity

Patterns

  • Configuration over code - Use data structures to eliminate conditionals
  • Template Method - Define skeleton in base, vary steps in subclasses
  • Dependency Injection - Parameterize dependencies to reduce coupling
  • Builder - Construct complex objects incrementally

Best Practices

  • Refactor only after tests pass (green)
  • Apply one refactoring at a time
  • Commit changes frequently
  • Name abstractions for intent, not implementation
  • Consider performance impact of abstractions
  • Review abstractions with team before finalizing
Weekly Installs
3
GitHub Stars
73
First Seen
Jan 23, 2026
Installed on
trae1
opencode1
claude-code1
antigravity1
gemini-cli1