Refactoring aims to change software’s static structure – the source code. It’s not often so much about the performance (run-time), but rather how a developer perceives the source code. You might even say, the ‘elegance’ or ‘beauty’ of the code.
Refactoring itself can be a beneficial mental process, during which developer takes a second glance at the form of the solution; it might also reveal bugs.
Let’s take a look at 2 fundamental cases.
A Stretch (and its rebound)
Many times there are phases in a software project, during which a developer ‘stretches’: makes an adamant commitment to work until a feature works; however rudimentary, but still it “works”.
Say, you’re making the network connectivity features, and the first RESTful API call requires some more boilerplate code than you ever thought.
The concept is something that you know is viable, so you start stretching the solution: create all variables you might need; crunch the call string (don’t care yet how it looks), and fire a first call to see what possibly happens. You get an answer, so lo and behold! You know the server has received your packet of data! That’s great!
Encouraged by this you add bit more to the code to really get going. In fact, you need to do some parsing on the return packet. Then you need to wire the error handling code, and… more. You now got some 50 lines of code, which indeed seems to work.
You are pacing forward, doing the simplest and most rudimentary code that will get the job done. The intermediary product, you know for sure, is full of bad practices, but that’s ok – for a while. You know that the code gets a second review and things will be refactored.
Stretch as combat experience
Making brave stretches is indeed quite an important part of programming. During a stretch, it might feel uncertain and being out there in a jungle, without a compass, you as a developer are also putting a lot at stake: there’s a chance that the solutions a) won’t work b) was completely the wrong one to begin with. But nevertheless those stretches are crucial for keeping the velocity (going forward) in a project. You are trading risk for risk: by taking some risk you alleviate the risk of being faced with an unknown task, of whose complexity you cannot say anything certain. Now that you’ve done the rudimentary code, you know a thing is doable, and you know the basic solution structure. Even if you wouldn’t accomplish a working solution, you have gained experience of the problem domain.
What about the promise of cleaning up?
If you ever played with LEGOs, or had a hobby that required building stuff with your hands and tools, you know how lucrative it is to “forget” cleaning up. Putting tools in their own place, cleaning trash, collecting and organizing stuff is rote task compared to the challenge of conceiving something novel. Having spent time in perfect flow, and probably feeling either accomplishment (or apathy for the lack of it), cleaning up and restructuring the code feels like an inferior task.
So, to recap: the tendency to favor even hasty development to stagnation is actually very healthy. The thing that’s often forgone is that if you never clean up the mess, it’s going to be what you’ll stare for a long time – maybe not this month, or even this year, but believe me – there are no code gremlins that tidy up things automatically for you, when you’re asleep.