Refactoring
Overview
Procedure for systematically improving code structure without changing behavior
Principles
Behavior Preservation
{‘description’: ‘Refactoring MUST NOT change what the code does.\nOnly how it does it.\n’, ‘verification’: [‘All existing tests still pass’, ‘All known use cases still work’, ‘No new bugs introduced’]}
Incremental Changes
{‘description’: ‘Make small changes, one at a time.\nVerify each change before the next.\n’, ‘benefits’: [‘Easier to find problems’, ‘Can stop at any point’, ‘Reviewable changes’]}
Test Safety Net
{‘description’: “Tests must exist before refactoring.\nIf they don’t, write them first.\n”, ‘rule’: ‘Never refactor without tests covering the behavior’}
Steps
Step 1: Assess current state
Understand what needs refactoring and why:
- Identify code smells and problems
- Understand current behavior
- Map dependencies and usage
- Assess test coverage
- Identify constraints and risks
- Define clear success criteria
Step 2: Ensure test coverage
Make sure you have a safety net before refactoring:
- Review existing tests for the code
- Identify coverage gaps
- Write characterization tests for untested behavior
- Verify tests pass before any changes
- Consider adding higher-level tests for safety
Step 3: Plan refactoring approach
Design a safe path to the goal:
- Break refactoring into small steps
- Order steps to maintain working state
- Identify points where you can stop
- Plan verification between steps
- Consider parallel change pattern for risky changes
- Set scope boundary (avoid scope creep)
Step 4: Execute refactoring
Perform the refactoring incrementally:
- Make one small change
- Run tests immediately
- Commit if tests pass
- Repeat for next change
- Stop if tests fail, fix before continuing
- Take breaks and review progress
Step 5: Verify behavior preservation
Confirm refactoring didn’t change behavior:
- Run full test suite
- Review changes for behavior modifications
- Test manually in key scenarios
- Check edge cases
- Verify performance is acceptable
- Review with another developer
Step 6: Clean up and document
Finalize the refactoring:
- Remove any dead code created
- Update documentation if needed
- Remove temporary scaffolding
- Ensure consistent style
- Write commit messages explaining changes
- Update team on changes made
Step 7: Review and learn
Extract lessons from the refactoring:
- Was the goal achieved?
- What remaining debt exists?
- What would we do differently?
- Should similar code be refactored?
- Are there process improvements?
- Document lessons learned
When to Use
- Code is difficult to understand or modify
- Adding features requires touching many files
- Bugs keep appearing in the same areas
- Code duplication is causing maintenance burden
- Performance optimization needs cleaner structure
- Preparing code for new functionality
- Technical debt is impacting velocity
- Onboarding developers is taking too long
Verification
- All tests pass after refactoring
- Code behavior is unchanged
- Refactoring goal is achieved
- Code is cleaner/more maintainable
- Changes are reviewed and approved
- Documentation is updated
- Team understands the changes
Input: $ARGUMENTS
Apply this procedure to the input provided.