Refactoring for Breakthroughs
Posted13 Sep, 2019
Read Time2 mins
Updated29 Sep, 2019
Upfront designing of software is not easy, especially for large unpredictable projects. Refactoring and testing play a key for maturing codebases.
Even in an agile workplace, senior developers and architects still design software solutions upfront before digging into code. There are many problems that can’t be anticipated with planning. They must be handled as they arrive.
Big architectural designs made before gain working experience of the codebase can lead teams down the wrong path. Time is wasted reverting the changes later on.
Healthy Organic Software
So, here is the key insight. Instead of forcing an ideal design upfront, let the codebase evolve organically. This can bring the best result with the least effort.
Evolve Organically? Is the codebase a plant? No. By Evolving organically, I’m referring to progressive refactoring. Refactoring is the art of changing structure without touching behaviour.
Development time tends to bounce between writing new code and refactoring old code. We refactor code because it:
- makes code easy to understand
- prepares code for anticipated changes
- reduces duplication of logic
- improves algorithmic efficiency
Good refactorings add value and experience. Add up enough experience via refactorings over time and developers naturally connect the dots that lead to breakthrough redesigns. The nuances behind these breakthroughs happen due to many factors. This include frustrations, conversations, research, repeated exposure, and pattern recognition encountered during the development process.
These refactoring are great and should be encouraged but they entail the risk of regression, when previously working code breaks. That’s why test-driven development (TDD) is a MUST for safe refactorings.
Red Green Refactor
TDD in a nutshell. Write a little test. Write enough code to make it pass. Refactor the code. Rinse and repeat.
With good tests, you refactor with confidence and boldness. You play with arrangements until you find one that works best for the moment. These refactorings are quick, simple, and enjoyable. You do this while adding functionality in bite sized pieces.
The tests act as safety nets. When you break code, you’re notified. You know what broke the code, thus avoid countless hours of headache. If you spend the time upfront writing good test, it saves time and cost when the codebase is much larger.
With a growing codebase, breakthroughs help keep feature additions manageable. A large codebase has many moving parts, so it can be intimidating to change things. Having good tests reassures us that we can develop with piece of mind.
I've summarized these ideas in my own words from James Shore's presentation at AssertJS 2019. From his presentation and my own experience with testing and refactoring, I wrote this blog post. I'm happy to hear your feedback. Thanks for reading.