Code Refactoring
Quick Reference
- •Templates: See templates.md for reporting refactoring results
Core Principle
NO REFACTORING WITHOUT TESTS FIRST
Refactor safely: tests first, incremental changes, verify behavior preserved.
When to Use
Use when encountering:
- •Code duplication (DRY violations)
- •Long functions (>50 lines)
- •High complexity (cyclomatic complexity >10, nested conditionals)
- •Placeholder functions (
pass,raise NotImplementedError) - •Magic numbers/strings
- •Deep nesting (>3 levels)
- •Large classes (>300 lines, multiple responsibilities)
Don't refactor when:
- •Code works correctly and is rarely touched
- •Refactoring would break functionality without tests
- •Time pressure requires shipping first (document debt, refactor later)
Safe Refactoring Workflow
Phase 1: Identify Target
- •
Detect Code Smells
- •Long functions (>50 lines)
- •High complexity (>10 decision points)
- •Duplication (similar code 2+ places)
- •Placeholder functions
- •Magic numbers/strings
- •Deep nesting (>3 levels)
- •
Understand Current Behavior
- •Read code carefully
- •Trace execution paths
- •Identify dependencies
- •
Assess Impact
- •What code calls this?
- •What tests exist?
- •What would break?
Phase 2: Write Tests (If Missing)
REQUIRED: If no tests exist:
- •Write tests capturing current behavior
- •Run tests to establish baseline
- •All tests must pass before refactoring
- •Cover: happy path, errors, edge cases, boundaries
Phase 3: Refactor Incrementally
One change at a time:
- •Make smallest possible change (extract one method, rename one variable)
- •Run tests after each change (must pass)
- •Commit frequently with clear messages
- •Verify behavior unchanged
Phase 4: Verify
- •Run all tests (must pass)
- •Check code quality (linter, type checker)
- •Document changes
Refactoring Patterns
Extract Method
When: Long function, duplicated code, complex logic
Process:
- •Identify code block to extract
- •Create new method with descriptive name
- •Move code, replace with method call
- •Run tests
Extract Class
When: Class has multiple responsibilities, large class
Process:
- •Identify cohesive group of data/behavior
- •Create new class
- •Move fields and methods
- •Delegate calls
- •Run tests
Eliminate Duplication
When: Same code appears in multiple places
Process:
- •Identify duplicated code
- •Extract common code to method/class
- •Parameterize differences
- •Replace all occurrences
- •Run tests
Replace Placeholder
When: Function has pass, raise NotImplementedError
Process:
- •Check if function is called (YAGNI)
- •If unused: Remove
- •If used: Implement functionality
- •Write tests
- •Run tests
Reduce Complexity
When: High cyclomatic complexity, deeply nested conditionals
Process:
- •Extract conditions to methods with descriptive names
- •Use early returns/guard clauses
- •Replace nested ifs with flat structure
- •Consider polymorphism for type-based conditionals
- •Run tests
Extract Constant
When: Magic numbers/strings in code
Process:
- •Identify magic number/string
- •Create constant with descriptive name
- •Replace all occurrences
- •Run tests
Code Smell Quick Reference
| Smell | Detection | Refactoring |
|---|---|---|
| Long function | >50 lines | Extract Method |
| High complexity | >10 decision points | Extract Method, Simplify Conditionals |
| Duplication | Same code 2+ places | Extract Method, Extract Class |
| Placeholder | pass, NotImplementedError | Implement or Remove |
| Magic numbers | Unexplained constants | Extract Constant |
| Deep nesting | >3 levels | Extract Method, Early Return |
| Large class | >300 lines | Extract Class |
Red Flags - STOP and Reassess
- •Refactoring without tests
- •Multiple changes in one commit
- •Tests failing after refactoring
- •Changing behavior while refactoring
- •Large refactoring without incremental steps
Integration with TDD
REQUIRED: Use testing skill before refactoring:
- •If tests exist: Run them, ensure all pass
- •If tests missing: Write tests using TDD workflow
- •Refactor incrementally
- •Run tests after each change
- •All tests must pass before proceeding
Refactoring is part of TDD REFACTOR phase - improve code structure while keeping tests green.
Common Mistakes
| Mistake | Fix |
|---|---|
| Refactor without tests | Write tests first, establish baseline |
| Change behavior | Refactor = same behavior, better structure |
| Too many changes at once | One change per commit, test after each |
| Ignoring failing tests | Fix tests or revert refactoring |
The Bottom Line
Refactoring improves code without changing behavior.
Tests first. Incremental changes. Verify after each step. Preserve behavior always.