TDD Refactor Phase - Improve Code Quality and Design
Quality Gates
- Definition of Done adherence - Ensure all tests are passing by running all tests before starting any activity.
- Code smells - Identify and eliminate code smells such as duplicated code, long methods, large classes, and complex conditionals.
- Security requirements - Address any security considerations.
- Performance criteria - Meet any performance requirements.
Core Principles
Code Quality Improvements
- Remove duplication - Extract common code into reusable classes and methods. Follow the "Rule of Three" meaning knowledge should be abstracted only after it has been used in three places.
- Improve readability - Use intention-revealing names and clear structure aligned with the domain.
- Apply SOLID principles
- Single Responsibility Principle - Ensure each class and method has one and only one reason to change.
- Open/Closed Principle - Make code open for extension but closed for modification.
- Liskov Substitution Principle - Subtypes must be substitutable for their base types.
- Interface Segregation Principle - Use specific abstract classes rather than general ones.
- Dependency Inversion Principle - Depend on abstractions, not concrete implementations.
- Simplify complexity - Break down large methods, reduce cognitive and cyclomatic complexities.
Design Excellence
- Class length - Keep the length of classes under 100 lines.
- Method length - Keep the length of methods under 10 lines.
- Composition over inheritance - Prefer writing small focused classes and compose behaviour from them.
- Dependency injection - Use dependency injection through class constructor arguments.
- Modularization - Organize code into coherent modules and packages.
- Pydantic models - Leverage Pydantic for configuration objects, data, and domain models.
Test Quality
- Fast tests - Ensure tests remain fast and isolated.
- Coverage maintenance - Test coverage must not decrease during refactoring.
Safe Refactoring Patterns
Use battle-tested refactoring techniques:
- Extract Constant - Move magic numbers and strings to named constants.
- Extract Method - Break down long methods into smaller ones.
- Extract Class - Split large classes with multiple responsibilities.
- Rename - Use intention-revealing names for variables, methods, and classes.
- Inline Variable/Method - Simplify code by removing unnecessary indirection.
- Move Method/Field - Relocate code to more appropriate locations.
- Replace Conditional with Polymorphism - Use objects instead of complex conditionals.
Documentation
- Update documentation - Revise inline comments and docstrings to match refactored code. Ensure the documentation always answers to question WHY instead of WHAT.
- Record decisions - Document non-obvious design decisions made during refactoring.
Performance & Quality Validation
- Avoid premature optimization - Only optimize when there are actual performance issues.
- Remove dead code - Eliminate unused imports, variables, and unreachable code.
- Run static analysis - Use linters and type checkers to catch issues early.
Execution Guidelines
- Ensure green tests - All tests must pass before refactoring can start. Verify this by running all tests.
- Small incremental changes - Refactor in tiny, atomic steps.
- Apply one improvement at a time - Focus on a single refactoring technique.
- No test code modifications - Do NOT modify any test code during refactoring.
- Continuous testing - Run tests after EACH and EVERY change.
- Coverage preservation - Ensure test coverage doesn't decrease during refactoring.
- Static analysis - Run linters and static analysis tools after changes.
- API stability - Validate that publicly exposed APIs and contracts remain unchanged.
- Rollback readiness - Revert to a previous working state when tests become unstable or complexity increases to the point you cannot reason about the changes.
Refactor Phase Checklist
Before Starting
- All tests pass before starting.
- Current test coverage recorded.
During Refactoring
- Linters and static analysis tools run successfully.
- Tests pass after every change.
- Specific refactoring technique documented.
- No modifications made to test code.
After Refactoring
- Code readability and design improved.
- All tests remain green.
- Test coverage is maintained or improved.
- Public APIs and contracts unchanged.
- Unused code removed (imports, variables, dead code).
- Documentation updated (comments, docstrings).
- Performance improved where applicable.
Technical Debt
- Remaining refactoring opportunities documented and suggested to the user.
- Non-obvious design decisions recorded.
- Breaking changes or impacts flagged.
Converted and distributed by TomeVault — claim your Tome and manage your conversions.