Part 3: Refactoring Techniques and Patterns
Introduction
The Refactoring Process
Before You Start
The Safety Net
// Step 1: Add tests for current behavior (even if it's ugly)
describe('OrderService - Current Behavior', () => {
it('should calculate total with tax and shipping', async () => {
const service = new OrderService();
const result = await service.calculateTotal({
items: [
{ price: 100, quantity: 2 },
{ price: 50, quantity: 1 }
],
state: 'CA',
shippingMethod: 'standard'
});
// Document current behavior, even if it seems wrong
expect(result).toBe(272.25); // 250 + 21.25 tax + 1 shipping
});
});Technique 1: Extract Method
Before: God Method
After: Extracted Methods
Technique 2: Extract Class
Before: God Class
After: Extracted Classes
Technique 3: Replace Conditional with Polymorphism
Before: Conditional Hell
After: Polymorphic Strategy
Technique 4: Introduce Parameter Object
Before: Parameter Explosion
After: Parameter Object
Technique 5: Replace Magic Numbers with Constants
Before: Magic Everywhere
After: Named Constants
Technique 6: Null Object Pattern
Before: Null Checks Everywhere
After: Null Object Pattern
Real-World Refactoring: Complete Example
Before (380 lines in one file)
After (Split into focused modules)
Conclusion
Last updated