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
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
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
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:
Metric Claude (Methods) Gemini (Pipeline) Cursor (Strategy)
Lines of Code 180 120 220 Cyclomatic Complexity 8 3 5 Test Coverage 95% 90% 98% Readability Score ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐ Testability ⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐⭐⭐⭐ Winner Good ✅ Best balance Overengineered
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.
# 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
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
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:
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
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
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:
Big Bang Refactoring
❌ “Rewrite everything at once”
✅ Small, incremental changes
Refactoring Without Tests
❌ “Tests are old, we’ll add them later”
✅ Tests first, then refactor
Changing Behavior
❌ “While I’m here, I’ll also fix this bug”
✅ Refactor OR fix bugs, not both
Premature Optimization
❌ “This might be slow someday”
✅ Profile first, optimize only if needed
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"
Use Feature Flags for Big Refactorings
// 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.