In part I of our refactoring series we talked about what is code refactoring, and why it deserves an investment during development. Part II was all about when to choose to refactor, what situations it's absolutely crucial to refactor in, and our teams take on the clean code approach. In Part III we highlighted consideration points and risks before refactoring and shared techniques to ensure you've got refactoring down.
In Part IV we go through common signs that signal it's time to refactor and in the next section we share step-by-step examples, tools, and resources for refactoring.
Make sure to come back every Wednesday for more tech shorts, how-tos, and deep dives into engineering tools and processes.
How do you know what should you refactor?
Every time you see code that's readability could be improved, refactoring should be done. Here's how to identify common signs in the code that you should refactor.
- Library versions are out-of-date
Every technology used to code your product should have a package manager which is responsible for listing and managing project dependencies. It will also contain information on versions used to build the product. Having your versions updated lowers your risk of security loopholes, support, and backwards compliance for past versions being limited or even ceased.
- Commits weren't done regularly
Commit history is a code repository that tracks changes done to code. If the latest commit was done months ago, this is a red flag that the code needs to be updated and refactored before any further work can be done on the product.
- Lack of documentation
If your code is documented it means it has the business context around it explained in a text file. If it's missing, it means three things:
- Shortcuts have been taken during development to speed up work
- Expect to find problems with upholding high standards of code structure
- With no business context, anyone new who works on the code will have difficulty navigating and working on it
- No unit test coverage
Unit tests are written to isolate a piece of functionality used to automate validating performance. They remain in the codebase and become increasingly helpful in detecting issues and whether the features have been coded properly and how they react when scaled. Without unit tests, refactoring is usually done blind, without concrete information on failures in code execution, what went sideways and knowing what to fix ends up being a hit or miss situation.
- Repository structure is messy
Repository structure should be clear and easily understandable, even for a non-technical person. This crucial to maintain for the team to be able to navigate and work with the code. It's core components should be easy to identify with clear differentiation between code verticals (modules).
- Code that doesn't uphold best development practices
Code should follow a pattern called Single Responsibilty Principle where each piece of the code is easily readable and each script clues in what it does. Additionally, functions and objects suggest what they do and results they produce, this removes unpredictability and complexity when changes are made.
- Excessive commented out code
Code that is commented out is considered "out of order" and not executed. This is big red flag - it indicates poor quality. Code changes that are waiting to be implemented sometime in the future or a problem with a specific script that no one had time to fix are common reasons for settling and just commenting it out.
- Comments with no context
If a comment serves to add context that wouldn't be deductible just by screening a function or a script, its considered a valuable insight and is kept for the future. However sometimes developers add in comments without context and instead explain their thought processes, this usually means refactoring needs to happen.
- Making changes feels like you're building from scratch
If making changes feels like you're building from scratch (time wise) and each commit is made because of bugs, unpredictable code behavior, and crashes, its time for refactoring. Most of the time you'll hear from your delivery team " we did not see that coming" and "we have no idea why this is happening". This is a guarantee that the code suffers from technical debt and it probably lacks unit tests. As a warning - working with code that signals these red flags will inevitability result in the product malfunctioning in almost all domains and source code, most teams consider this time of code beyond saving and end up building from scratch.
- Performance declines as traffic increases
If a product's performance declines or crashes as user traffic increases this means your code is not optimized to scale to demand. Refactoring will remedy this but you should have future development plans to improve your product's scaling abilities.
- Give variables meaningful names
Sometimes it's less obvious, but when we look at problematic code, we can feel that something is not right, it smells (code smell, also referred to as heuristics). Instead of writing comments above the variables, give them meaningful names.
- Micro-optimized code is much harder to read
But if it's a critical optimization, you should only refactor it to make it more readable when it doesn't decrease the performance. Even if the impact is noticeable, go with the slower but more readable code. The reason is - it's cheaper to buy hardware with more performance than a developer's additional cost because code is harder to maintain.
- Martin Fowler - Refactoring Starting Point Code Example
- Baeldung examples of advanced refactoring
- Wouter Lagerweij step by step refactoring example
- Dzone Refactoring patterns
- Martin Fowlers book paraphrased
- Martin Fowlers Refactoring book on Amazon
- Uncle Bob's Clean Code book on Amazon
- Jeffrey Way video of refactoring multiple levels of code
- Knowthecode video example of refactoring
- GitHub - Jedi autocompletion, static analysis, and refactoring library
- Github - Complete project to show how to apply DDD, Clean Architecture, and CQRS by practical refactoring.
- Refactoring essential for VS
- Code Refactoring Tisp for C#
- VS code refactoring tools
- 5 Best JetBrain Extensions for refactoring