Refactoring is good right? We constantly read about how we should be writing simple and easy code to do the minimum necessary and refactoring it as we go to improve it and expand what it can do. Unfortunately, this can lead to some really bad habits, especially if it’s used as a displacement activity.
What do I mean by displacement activity? Well lets consider a hideous project that is under specced, under resourced and overdue. Our poor old developer is demotivated and drowning under a sea of requirements that they don’t know how they’re going to implement, but what they have done is written the code that handles the command line arguments. This code works to spec, is even tested and could be considered complete. But, it’s taking user input. It’s not as neat as it could be. In fact it’s quite messy.
So what does our developer do? Do they tackle the next in the long list of requirements and try and get closer to completion, or do they refactor the working code to make it nicer? While we all know they should be doing the former, all to often it’s the latter that happens. Our developer goes off and refactors the working code to make it nicer.
Having seen this happen on a number of occasions it got me to thinking what was going on here. Why mess about with the stuff that works when there is a pile of stuff that doesn’t work to be getting on with. The answer is brutally simple, it’s a psychological trick.
In order to feel that they have had a productive day our developer needs to make progress. By tackling the difficult, as yet unwritten features, the developer is taking a risk. They may not be able to complete the task in the time they’ve allotted. They may run into problems. They may get stuck. They may fail. By refactoring the working code, on the other had, they’re tackling a problem that they know they can solve; after all, they’ve solved it already. What they’re doing now is a refinement.
Of course, once the refinement is completed our developer is still left with the mountain of requirements to complete that they didn’t want to tackle, and they now have less time to complete those requirements, but dealing with that problem has been shifted to something we can deal with tomorrow. In the mean time “progress”, for a given definition of progress, has been made because the existing code is now cleaner. A classic displacement activity.
Taken to its extreme this kind of thinking can lead to making nothing absolutely perfectly. You tend towards, but never actually achieve, the perfect solution for your problem. This is compounded by the fact that as soon as you start dealing with the edges of software development (input and output) things start getting messy. Perfection can’t actually be achieved and you’ll end up swapping one compromise for another ad-infinitum. Annoyingly we know all about this pitfall. the KISS principle and MVPs are all about avoiding this type of displacement and producing something that is important: working code. The irony is that this “perfect code” that we’ve wasted time crafting will no doubt get hacked about later as the system grows and the missing requirements are added. One day we may learn.