Build, refactor, repeat
January 26, 2022 · 3 minute read
One of my aims this year is to up my refactoring game.
I’ve come to realise that striving to write perfect, or even good code right off the bat is antithetical to making progress and delivering working software.
There are a couple of reasons for this.
First, the brain struggles to do two things at once, specifically in this case solving a functional requirement at the same time as writing ‘good’ code.
The danger is we end up doing neither very well; paralysed, we neither make progress with the feature nor write very good code!
Second, any attempt to build too much structure into code before we’ve implemented a feature means pre-judging what that code will require, how complex it will be, and what shape it will take.
That’s right, the old ‘if the only tool in your toolbox is a hammer, everything looks like a nail’ problem of prematurely adopting a pattern, architecture, approach before there’s enough evidence to nudge you towards it.
As soon as we’ve implemented a few design patterns and separated the code into multiple classes we’ve potentially put our feature into a straight-jacket, from which escape is often difficult, sometimes impossible.
I’ve found the best counter to this is to focus on implementing the feature first, writing the simplest code that works. It doesn’t matter if the code is ‘good’ or not (for now).
At this first opportunity to make the logic work, anything goes…
On one condition.
As soon as you know the logic works, it’s important to look at the resulting code with fresh eyes and take a little time to refactor it.
If this sounds familiar, it may be because this is the general approach advocated by TDD (red, green, refactor).
But if you don’t have a strong TDD, or testing practice in general, don’t beat yourself up.
I mean sure, it’s probably worth trying to find ways to build a better testing habit, but you can still take this approach of solving a small requirement then refactoring once it’s working. Just be aware that you won’t have any automated test to prove you haven’t broken anything in the refactor, which makes the process riskier.
(I say this because it’s all too easy to let frustration and especially guilt stop us from employing good practices. If this is you, cut yourself some slack; then you’ll be in the right head space to try a different approach).
As I focus on refactoring this year I’m actively seeking useful resources.
Last year I found Jimmy Bogard’s series on Domain-Driven refactoring particularly interesting/useful.
Do you know any good resources for upping your refactoring game? Feel free to share in the comments below :)