Refactoring is a key concept in the Agile development world. Refactoring is the practice of continuously improving the existing code base, without changing the existing product behavior.
Refactoring addresses the “debts” in the product which tend to accumulate over the years:
- Quality debts
- Design debts
- Technology debts
- Test debts
Refactoring isn’t rewriting or fixing bugs – it’s all about improving the internal structure of the existing source code to be of a better quality.
When considering a code refactoring, three essential questions are asked and responded by the team, in order to prepare the refactoring scope and strategy:
- What changes do we have to make?
- How will we know that we’ve done them correctly?
- How will we know that we haven’t broken anything?
The best practices our company uses for code refactoring projects and tasks are:
- Do not plan code refactoring as a standalone task, but do “continuous refactoring” – the code should constantly improve – every Sprint, the code is at least slightly better than it was the previous Sprint.
- Perform code refactoring in small chunks
- Avoid the temptation to do large redesigns in single steps
- Use standard software design patterns when refactoring
- Measure success – measure code complexity, maintainability etc. A refactored code is one for which:
- Code quality is improved
- Complexity is reduced
- Maintenance is easier
- Code readability is improved
- It is easier to add new features
- “Get it working, but don’t write bad code”
- Use the “Rule of Three”: The first time you do something, you just do it. The second time you do something similar, you wince at the duplication, but you do the duplicate thing anyway. The third time you do something similar, you refactor.
- Balance the need to deliver on time with the need to have good code.
When our teams do code refactoring (including reviews), we use the following checklist to analyze the code refactoring work:
- Coding standards
- Code complexity
- Code clones
- Dead code detection
- Projects structure
- File and directory layout
- Design conventions
- Error handling and assertions
- Approach to events and logging