Skip to main content

Overview

Refactoring with Forge lets you improve code structure without fear. Git worktree isolation means you can experiment boldly, compare different refactoring approaches, and only merge when you’re certain the code is better.

The Refactoring Cycle


When to Refactor

Code Smells

  • Duplicated code
  • Long functions (>50 lines)
  • Complex conditions
  • Poor naming
  • God objects/classes

Right Time

  • Before adding new features
  • After fixing bugs
  • During code review
  • When tests are green
  • NOT under pressure
Never refactor:
  • Without tests
  • Under deadline pressure
  • Multiple things at once
  • Based on guesswork

Step 1: Safety First - Write Tests

Before refactoring, ensure comprehensive test coverage.
# Check current test coverage
forge task create \
  --title "Measure test coverage for auth module" \
  --description "Generate coverage report, identify gaps" \
  --agent claude-code \
  --labels "testing,refactor-prep"

# Add missing tests
forge task create \
  --title "Add tests for auth edge cases" \
  --description "Ensure 100% coverage before refactoring" \
  --agent claude-code \
  --labels "testing"
Golden Rule: All tests must be green before starting refactoring. If tests fail, fix them first.

Step 2: Define Clear Goals

Know exactly what you’re improving and how you’ll measure it.

Example Goals

  • Readability
  • Performance
  • Maintainability
  • Reusability
Before: “Clean up the code” Better: “Split 300-line UserService into 3 focused classes, each under 100 lines”
forge task create \
  --title "Refactor: Split UserService into focused modules" \
  --description "Create AuthService, ProfileService, PreferencesService" \
  --agent claude-code

Step 3: Experiment with Multiple Approaches

Try different refactoring strategies using different agents.

Example: Refactoring Large Function

1

Approach 1: Extract Methods (Claude)

// Original: 150-line processOrder function

// Claude's approach: Extract small, focused methods
class OrderProcessor {
  processOrder(order: Order) {
    this.validateOrder(order);
    this.calculateTotal(order);
    this.applyDiscounts(order);
    this.processPayment(order);
    this.updateInventory(order);
    this.sendConfirmation(order);
  }

  private validateOrder(order: Order) { /* ... */ }
  private calculateTotal(order: Order) { /* ... */ }
  // etc.
}
Pros: Clear, testable methods Cons: Many small methods
2

Approach 2: Pipeline Pattern (Gemini)

// Gemini's approach: Functional pipeline
const processOrder = pipe(
  validateOrder,
  calculateTotal,
  applyDiscounts,
  processPayment,
  updateInventory,
  sendConfirmation
);
Pros: Functional, composable Cons: Requires pipeline utility
3

Approach 3: Strategy Pattern (Cursor)

// Cursor's approach: Strategy objects
class OrderProcessor {
  constructor(
    private validator: OrderValidator,
    private calculator: PriceCalculator,
    private payment: PaymentProcessor,
    private inventory: InventoryManager,
    private notifications: NotificationService
  ) {}

  processOrder(order: Order) {
    this.validator.validate(order);
    const total = this.calculator.calculate(order);
    this.payment.process(order, total);
    this.inventory.update(order);
    this.notifications.sendConfirmation(order);
  }
}
Pros: Highly testable, SOLID Cons: More boilerplate

Compare Approaches

# Create all three attempts
forge task create --title "Refactor processOrder" --agent claude-code
forge task fork task-1 --agent gemini
forge task fork task-1 --agent cursor-cli

# Compare results
forge task compare task-1

# Metrics to compare
forge task metrics task-1-attempt-1 \
  --measure "lines-of-code,cyclomatic-complexity,test-coverage"
Comparison Matrix:
MetricClaude (Methods)Gemini (Pipeline)Cursor (Strategy)
Lines of Code180120220
Cyclomatic Complexity835
Test Coverage95%90%98%
Readability Score⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
Testability⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
WinnerGoodBest balanceOverengineered

Step 4: Verify Everything Still Works

After refactoring, run comprehensive verification.
# Run full test suite in refactored worktree
forge task test task-1-attempt-2

# Compare test results with main branch
forge task test-diff main task-1-attempt-2
All tests must pass. No exceptions.
# Benchmark before and after
forge task create \
  --title "Benchmark refactored code vs original" \
  --description "Compare memory usage, execution time, throughput" \
  --agent gemini

# Results should show improvement or no regression
# Integration tests
forge task create \
  --title "Run integration tests for order processing" \
  --agent claude-code

# Manual smoke tests
forge task create \
  --title "Manual testing checklist for order flow" \
  --description "Test happy path, edge cases, error scenarios" \
  --agent gemini
# Linting
forge task run "npm run lint" task-1-attempt-2

# Type checking
forge task run "npm run typecheck" task-1-attempt-2

# Code complexity analysis
forge task run "npm run complexity" task-1-attempt-2

Common Refactoring Patterns

1. Extract Function/Method

When: Function is too long or has multiple responsibilities
forge task create \
  --title "Refactor: Extract calculateShipping from processOrder" \
  --description "Move shipping calculation to separate function" \
  --agent gemini  # Gemini is fast for simple extractions

2. Extract Class

When: Class has too many responsibilities
forge task create \
  --title "Refactor: Extract EmailService from UserService" \
  --description "Move all email-related logic to EmailService" \
  --agent claude-code  # Claude handles complex extractions well

3. Rename for Clarity

When: Names are unclear or misleading
forge task create \
  --title "Refactor: Rename ambiguous variables in auth module" \
  --description "data->userData, temp->sessionToken, flag->isAuthenticated" \
  --agent cursor-cli  # Cursor's LSP integration helps with safe renames

4. Introduce Parameter Object

When: Function has too many parameters
forge task create \
  --title "Refactor: Replace parameters with UserCreateDTO" \
  --description "Combine name, email, phone, address into single object" \
  --agent claude-code

5. Replace Conditional with Polymorphism

When: Complex if/switch statements
forge task create \
  --title "Refactor: Replace payment type switch with strategy pattern" \
  --description "Create PaymentStrategy interface with CreditCard, PayPal, Crypto implementations" \
  --agent cursor-cli

6. Remove Duplication

When: Same code appears in multiple places
forge task create \
  --title "Refactor: Extract duplicate validation logic" \
  --description "DRY principle - create shared validator utilities" \
  --agent gemini

Real-World Example: Legacy Code Modernization

Complete refactoring of a legacy authentication module:
1

Week 1: Assessment & Testing

# Day 1-2: Understand current code
forge task create --title "Document legacy auth flow" --agent claude-code
forge task create --title "Map dependencies and touch points" --agent gemini

# Day 3-5: Add tests
forge task create --title "Add unit tests (target 80% coverage)" --agent claude-code
forge task create --title "Add integration tests" --agent cursor-cli
forge task create --title "Create performance baseline" --agent gemini
2

Week 2: Incremental Refactoring

# Day 1: Extract services
forge task create --title "Extract AuthService from monolithic auth.js" --agent claude-code

# Day 2: Modernize syntax
forge task create --title "Convert callbacks to async/await" --agent gemini

# Day 3: Improve error handling
forge task create --title "Add proper error handling and logging" --agent claude-code

# Day 4: Type safety
forge task create --title "Add TypeScript types to auth module" --agent cursor-cli

# Day 5: Testing
forge task create --title "Verify all tests pass with refactored code" --agent claude-code
3

Week 3: Optimization & Review

# Day 1-2: Performance optimization
forge task create --title "Optimize token validation" --agent claude-code
forge task create --title "Add caching layer" --agent gemini

# Day 3-4: Security audit
forge task create --title "Security review of auth refactoring" --agent claude-code

# Day 5: Documentation
forge task create --title "Update auth documentation" --agent gemini

# Ship it!
forge task merge-all-approved

Refactoring Anti-Patterns to Avoid

Don’t Do This:

  1. Big Bang Refactoring
    • ❌ “Rewrite everything at once”
    • ✅ Small, incremental changes
  2. Refactoring Without Tests
    • ❌ “Tests are old, we’ll add them later”
    • ✅ Tests first, then refactor
  3. Changing Behavior
    • ❌ “While I’m here, I’ll also fix this bug”
    • ✅ Refactor OR fix bugs, not both
  4. Premature Optimization
    • ❌ “This might be slow someday”
    • ✅ Profile first, optimize only if needed
  5. Over-Engineering
    • ❌ “Let’s use 5 design patterns here”
    • ✅ Simplest solution that works

Measuring Refactoring Success

Track these metrics to ensure refactoring improved the code:
  • Code Metrics
  • Performance
  • Maintainability
  • Developer Experience
# Before and after comparison
forge task create \
  --title "Generate code metrics report" \
  --agent gemini

# Compare:
# - Lines of code (should decrease)
# - Cyclomatic complexity (should decrease)
# - Code duplication (should decrease)
# - Test coverage (should increase)

Pro Tips

Each commit should pass all tests:
# ✅ Good: One refactoring per task
forge task create --title "Extract calculateTax method"
forge task create --title "Extract calculateShipping method"
forge task create --title "Extract applyDiscounts method"

# ❌ Bad: Everything at once
forge task create --title "Refactor entire order processing"
// Deploy refactored code behind feature flag
const orderProcessor = featureFlags.isEnabled('new-order-processor')
  ? new RefactoredOrderProcessor()
  : new LegacyOrderProcessor();

// Gradually roll out, monitor for issues
forge task create \
  --title "Document refactoring decisions" \
  --description "ADR: Why we chose pipeline pattern over strategy pattern" \
  --agent gemini
# One agent refactors, another reviews
forge task create --title "Refactor auth module" --agent gemini
forge task create --title "Review auth refactoring" --agent claude-code

Next Steps


Remember: Refactoring is not about making code “perfect”. It’s about making it better, safer, and easier to maintain. With Forge’s isolation, you can experiment freely and choose the approach that truly improves your codebase.