Martin Fowler's refactoring catalog with incremental change patterns and test-driven refactoring discipline
Comprehensive refactoring guide based on Martin Fowler's "Refactoring: Improving the Design of Existing Code."
Small Change → Test → Commit → Repeat
Every refactoring must preserve existing behavior while improving code structure.
Identify One Small, Isolated Change
Make the Change
Run All Tests Immediately
Commit the Change
Repeat - Build on the previous improvement
RED → Write failing test for new feature
GREEN → Minimal code to pass test (can be ugly)
REFACTOR → Improve code in tiny increments (test after each)
→ ONLY when all tests are green
→ Commit after each improvement
Extract Method - Create well-named method from code fragment
Inline Method - Replace method call with method body
Inline Temp - Replace temp variable with direct method call
Replace Temp with Query - Extract expression to method, remove temp
Introduce Explaining Variable - Put complex expression in temp with clear name
Split Temporary Variable - Create separate temp for each assignment
Remove Assignments to Parameters - Use temp instead of assigning to parameter
Replace Method with Method Object - Turn method into its own class
Substitute Algorithm - Replace algorithm with clearer/simpler one
Move Method - Move method to class that uses it most
Move Field - Move field to class that uses it most
Extract Class - Create new class for subset of responsibilities
Inline Class - Merge class into another when it's no longer pulling weight
Hide Delegate - Create method to hide delegation
Remove Middle Man - Call delegate directly when middle man is thin wrapper
Replace Magic Number with Symbolic Constant
Encapsulate Field - Make field private, provide accessors
Encapsulate Collection - Return read-only view, provide add/remove methods
Replace Type Code with Class - Replace integer codes with class
Replace Type Code with Subclasses - Turn codes into inheritance
Replace Type Code with State/Strategy - Use State/Strategy pattern
Decompose Conditional - Extract condition and branches into methods
if (date.before(SUMMER_START)) → if (notSummer(date))Consolidate Conditional Expression - Combine conditions with same result
Consolidate Duplicate Conditional Fragments - Move identical code outside conditional
Remove Control Flag - Use break, continue, or return instead of flag variable
Replace Nested Conditional with Guard Clauses - Use early returns
if (!valid) return; // rest of methodReplace Conditional with Polymorphism - Move conditional to subclass methods
Introduce Null Object - Replace null checks with null object
Introduce Assertion - Make assumptions explicit
assert(balance >= 0, "Balance cannot be negative")Rename Method - Make name explain purpose
Add Parameter / Remove Parameter - Adjust parameter list
Separate Query from Modifier - Split methods that return value and change state
Parameterize Method - Use parameter instead of multiple similar methods
Replace Parameter with Explicit Methods - Create separate method for each value
Preserve Whole Object - Pass entire object instead of multiple values
Replace Parameter with Method - Remove parameter by calling method
Introduce Parameter Object - Group parameters into object
Remove Setting Method - Make field immutable after construction
Hide Method - Make method private if not used outside class
Replace Constructor with Factory Method - Return polymorphic type
Replace Error Code with Exception - Throw exception instead of returning code
Replace Exception with Test - Check condition first to avoid exception
Pull Up Field / Pull Up Method - Move to superclass when identical in subclasses
Push Down Field / Push Down Method - Move to subclass when used only there
Extract Subclass - Create subclass for features used in some instances
Extract Superclass - Create superclass for common features
Extract Interface - Create interface when classes share subset of features
Collapse Hierarchy - Merge subclass into superclass when too similar
Form Template Method - Move invariant steps to superclass, override variants
Replace Inheritance with Delegation - Use composition when subclass uses only part of superclass
Replace Delegation with Inheritance - Make delegate a subclass if using all features
Bad Approach (risky - batched changes):
// Extract 3 methods + rename 5 variables + reorganize imports
// Run tests → many failures → hard to debug
Good Approach (safe - incremental):
1. Extract calculateSubtotal() → test → commit
2. Extract calculateTax() → test → commit
3. Extract calculateTotal() → test → commit
4. Rename 'amt' to 'amount' → test → commit
5. Rename 'calc' to 'calculate' → test → commit
Based on Martin Fowler's "Refactoring: Improving the Design of Existing Code"