Legacy Code Management | Strangler Fig, Refactoring
Work with legacy code using the Strangler Fig pattern, incremental improvements, and test-first refactoring. Balance maintenance with new development.
7 min read
Legacy code requires careful handling to avoid breaking existing functionality while enabling new development. GitScrum helps teams track legacy-related work separately, plan incremental improvements, and maintain clear visibility into the balance between maintenance burden and feature development.
Legacy Code Strategies
| Strategy | When to Use | Effort |
|---|---|---|
| Add tests only | High-risk, frequently changed | Low |
| Extract and test | Module worth preserving | Medium |
| Wrap and replace | Strangler Fig pattern | Medium-High |
| Full rewrite | Obsolete, unmaintainable | High |
Working with Legacy Code
LEGACY CODE IMPROVEMENT FRAMEWORK
1. ASSESS THE LEGACY CODE
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β For each legacy component, evaluate: β
β β
β Change Frequency: β
β βββ High: Modified monthly β Priority β
β βββ Medium: Modified quarterly β Plan ahead β
β βββ Low: Rarely touched β Leave alone β
β β
β Bug Rate: β
β βββ High: Frequent bugs β Fix urgently β
β βββ Medium: Occasional bugs β Improve β
β βββ Low: Stable β Maintain β
β β
β Test Coverage: β
β βββ None: No tests β Add tests β
β βββ Low: < 40% β Improve β
β βββ Good: > 70% β Maintain β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
2. CATEGORIZE APPROACH
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β High Change Frequency β
β β β
β ββββββββββββΌβββββββββββ β
β β WRAP β EXTRACT β β
β β AND β AND β β
β β REPLACE β TEST β β
β β β β β
β ββββββββββββΌβββββββββββ€ β
β β DEFER β ADD β β
β β (costs β TESTS β β
β β exceed β ONLY β β
β β benefit)β β β
β ββββββββββββ΄βββββββββββ β
β Low Quality β High Quality β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
The Boy Scout Rule
INCREMENTAL IMPROVEMENT PRACTICE
RULE: Leave the code better than you found it
WHEN TOUCHING LEGACY CODE:
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β Before making your change: β
β 1. Add tests for the code you'll modify β
β 2. Verify tests capture current behavior β
β β
β Make your change: β
β 3. Implement the feature/fix β
β 4. Ensure tests still pass β
β β
β Leave it better: β
β 5. Small refactor (rename, extract method) β
β 6. Add any missing documentation β
β 7. Improve test coverage slightly β
β β
β Constraint: Improvement adds β€30% to task time β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
EXAMPLE:
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β Task: Add discount calculation to order β
β Time estimate: 3 hours β
β β
β Improvement time budget: ~1 hour β
β β
β Improvements made: β
β βββ Added 3 tests for existing calculateTotal β
β βββ Renamed confusing variable names β
β βββ Extracted duplicate logic to helper β
β βββ Added JSDoc for public methods β
β β
β Result: Feature works + code slightly better β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
Strangler Fig Pattern
GRADUAL REPLACEMENT STRATEGY
STRANGLER FIG APPROACH:
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β New features use new code β
β Old features gradually migrate β
β Legacy shrinks over time β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
IMPLEMENTATION:
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β PHASE 1: Create wrapper β
β ββββββββββββββββββββββββββββββββββββββββββββββ β
β β Consumers β Facade β Legacy Code β β
β ββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β PHASE 2: New implementation behind facade β
β ββββββββββββββββββββββββββββββββββββββββββββββ β
β β ββ New Code (new features)β β
β β Consumers β Facade β β
β β ββ Legacy (existing) β β
β ββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β PHASE 3: Migrate features to new code β
β ββββββββββββββββββββββββββββββββββββββββββββββ β
β β ββ New Code (80%) β β
β β Consumers β Facade β β
β β ββ Legacy (20%) β β
β ββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β PHASE 4: Remove legacy β
β ββββββββββββββββββββββββββββββββββββββββββββββ β
β β Consumers β Facade β New Code (100%) β β
β ββββββββββββββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
Legacy Backlog Management
LEGACY IMPROVEMENT TRACKING
BACKLOG STRUCTURE:
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β Project: Legacy Improvements β
β β
β Labels: β
β βββ [legacy-testing] - Add test coverage β
β βββ [legacy-refactor] - Code improvements β
β βββ [legacy-replace] - Module replacement β
β βββ [legacy-debt] - Technical debt items β
β β
β Capacity: 15% of team time per sprint β
β β
β Prioritization: β
β 1. Modules being actively modified β
β 2. High bug rate areas β
β 3. Performance bottlenecks β
β 4. Security concerns β
β 5. Developer frustration areas β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
TASK TEMPLATE:
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β Title: Add test coverage to PaymentService β
β Labels: [legacy-testing] [payments] β
β β
β Current State: β
β Test coverage: 12% β
β Bug rate: 3 bugs/month β
β Change frequency: High β
β β
β Goal: β
β Add tests for core payment flows β
β Target coverage: 60% β
β β
β Approach: β
β 1. List critical paths to test β
β 2. Create test fixtures β
β 3. Write tests for happy path β
β 4. Add edge case tests β
β β
β Acceptance: β
β β Coverage > 60% for PaymentService β
β β All existing tests still pass β
β β No behavior changes β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
Metrics Dashboard
LEGACY IMPROVEMENT METRICS
CODE QUALITY TRENDS:
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β Module: PaymentService β
β β
β Test Coverage: β
β Jan: 12% β Feb: 35% β Mar: 58% β Improving β
β β
β Bug Rate (per month): β
β Jan: 5 β Feb: 3 β Mar: 1 β Improving β
β β
β Change Velocity (time per change): β
β Jan: 4h β Feb: 3h β Mar: 2h β Improving β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
OVERALL LEGACY STATUS:
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β Total legacy modules: 45 β
β βββ Critical (needs attention): 8 β
β βββ Improving (work in progress): 12 β
β βββ Stable (acceptable state): 20 β
β βββ Modern (fully updated): 5 β
β β
β Trend: -3 critical modules this quarter β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
Best Practices
Anti-Patterns
β Changing legacy without tests
β Big bang rewrite attempts
β No time allocated for improvements
β Mixing feature + major refactor in one PR
β Only fixing when broken
β No metrics on legacy health