| name | refactoring |
| description | Safely refactor code to improve structure, readability, and maintainability without changing behavior. Use proven techniques and patterns. |
| triggers | ["/refactor","/code cleanup"] |
Safe Refactoring Techniques
This skill provides systematic approaches to refactoring code safely, improving structure and maintainability while preserving behavior.
When to use this skill
Use this skill when you need to:
- Improve code readability and maintainability
- Reduce technical debt
- Prepare code for new features
- Apply design patterns
- Simplify complex code
Prerequisites
- Comprehensive test coverage for the code to refactor
- Understanding of the codebase and dependencies
- Version control with clean history
- Time to verify behavior hasn't changed
Guidelines
Refactoring Principles
Golden Rule
- Never refactor without tests
- Make small, incremental changes
- Run tests after each change
- Commit frequently
When to Refactor
- Rule of Three: Similar code appearing 3+ times
- Adding a feature is harder than it should be
- Understanding code takes too long
- Code violates SOLID principles
- Performance optimization needed
Refactoring Workflow
Preparation
- Ensure tests exist and pass
- Review code to understand current behavior
- Identify specific issues to address
- Plan refactoring steps
Execution
- Make one small change at a time
- Run tests after each change
- Commit working states frequently
- Use IDE refactoring tools when possible
Verification
- All tests pass
- Code review by peer
- Verify in staging environment
- Monitor production after deployment
Common Refactorings
Extract Method
def process_order(order):
print(f"Processing order {order.id}")
if order.total > 1000:
print("High value order - requires approval")
send_notification(order.manager, "Approval needed")
update_inventory(order.items)
send_confirmation(order.customer)
def process_order(order):
log_order_processing(order)
if requires_approval(order):
request_approval(order)
fulfill_order(order)
def log_order_processing(order):
print(f"Processing order {order.id}")
def requires_approval(order):
return order.total > 1000
def request_approval(order):
print("High value order - requires approval")
send_notification(order.manager, "Approval needed")
def fulfill_order(order):
update_inventory(order.items)
send_confirmation(order.customer)
Introduce Parameter Object
def create_user(name, email, phone, address, city, zip_code):
pass
@dataclass
class UserInfo:
name: str
email: str
phone: str
address: str
city: str
zip_code: str
def create_user(user_info: UserInfo):
pass
Replace Conditional with Polymorphism
def calculate_salary(employee):
if employee.type == "fulltime":
return employee.base_salary
elif employee.type == "contractor":
return employee.hourly_rate * employee.hours
elif employee.type == "intern":
return 0
class FullTimeEmployee(Employee):
def calculate_salary(self):
return self.base_salary
class Contractor(Employee):
def calculate_salary(self):
return self.hourly_rate * self.hours
class Intern(Employee):
def calculate_salary(self):
return 0
Code Smells to Address
Bloaters
- Long methods → Extract methods
- Large classes → Extract classes
- Long parameter lists → Introduce parameter objects
- Data clumps → Extract classes
Object-Orientation Abusers
- Switch statements → Polymorphism
- Temporary fields → Extract classes
- Refused bequests → Replace inheritance with delegation
- Alternative classes → Unify interfaces
Change Preventers
- Divergent change → Split responsibilities
- Shotgun surgery → Move methods/fields
- Parallel inheritance → Bridge pattern
Dispensables
- Duplicate code → Extract common code
- Lazy classes → Inline or remove
- Data classes → Add behavior
- Dead code → Delete
Safety Techniques
Characterization Tests
When tests don't exist, write tests that capture current behavior before refactoring:
def test_current_behavior():
"""Document current behavior before refactoring."""
result = legacy_function(input_data)
assert result == expected_output
Parallel Implementation
Keep old implementation while building new:
def process_data(data, use_new_impl=False):
if use_new_impl:
return new_implementation(data)
return old_implementation(data)
Feature Flags
Enable gradual rollout of refactored code:
if feature_flags.enabled("new-payment-flow"):
process_payment_v2(order)
else:
process_payment_v1(order)
Examples
See the examples/ directory for:
extract-method-examples/ - Method extraction patterns
design-pattern-refactorings/ - Applying design patterns
legacy-code-techniques.md - Working with untested code
before-after-comparisons.md - Real refactoring examples
References