Should it be readable or should it work?
This question was posed to me by a junior programmer from my team a few months ago. The person was asking it aggressively and with frustration because the project was late and there was lots of pressure from the management to have the software delivered.
The answer in such a stressful situation is evident: Programs should work, otherwise they are just a list of characters or bytes. When adrenaline rushes there are only two choices: fight or run. That is the way our species survived during millions of years of evolution. But after a while, when you calm down you can start thinking. You end up with a working (really working?) bunch of code. It passed UAT, thus you are still alive, not fired and the Spanish inquisition packed their dreadful tools and went back to their offices on the top floor for a while. The sun shines again, the dark clouds vanished, for now. But what will come next after just two weeks when the next sprint finishes?
You take a deep breath and start to run again for the next sprint. The “working” code remains without re-factoring the way it is now. We need that code executing, and readability comes into play only when you want to modify the code. Code modification is not the focus for the moment. Delivering the next functionality, however, is. The project manager is swinging the whip above your head and you slowly realize that your code you imagined to be the best ever program on earth degrades to a heap of X (X can be different things based on your current mood, education and language versatility).
Any temporary code is terminal.
When you write a few lines of code to fix a bug and you put a //TODO in there, this has to be changed later, but you should know that the probability of making the change is very small. The code will remain as it is. In some cases it will be re-factored but that is even worse. Why? Let me explain!
Refactoring is usually done because a developer can't stand the spaghetti macrame the code became and devotes some “free” time to do the re-factoring or re-structuring. This is not a professional approach.
From the technological point of view it can be professional. There are unit tests, functional and integration tests, and all the bells and whistles that are needed for a professional refactor. The non professional part is the financing.
If you find free lunch, it's best not to eat it. You don't know why it was free.
It is not professional in the meaning that this is work done for pure enthusiasm and not for the money. This work is financed by someone, who is not the consumer of the product of the work. Such a situation is never professional. There is no free lunch, and what's more: you should want to pay for your lunch. That will ensure that you will have a quality lunch today, tomorrow and in the future, so long as long you pay for it. You need the lunch, they need the money. The same holds for programming. In other words: you will get what you paid for. Low price: no meat in the soup.
Refactors are like lunches. You better pay for it if you are in the customer's shoes. How much should you pay? How much refactoring will you really need to do to get the best code you can? This is a tricky question that is hard to answer.
Sometimes it is more important to have code that is readable than a code that works.
The key word in this sentence is: sometimes, i.e., when delivery is not in jeopardy. When posed with this decision, you can either do it Q&D (quick and dirty) and go for a beer (or bear if you are the hunter type), or DIR (do it right). I sometimes feel the urge to finish something fast, but not because I'm rushing for a beer (or bear). When running my code for the first time I feel like Victor Frankenstein seeing his creature’s first movement. But then, if it works, why mend it? I do not want to kill my creature just to have better looking code. That feeling when I can see bugs appearing that were not present ten minutes ago in the ugly code ... Yes, it was ugly, but it worked. Why did I started to re-factor it? And then I bang my head against the wall.
But there is a caveat: if the ugly code worked but the refined, good looking code does not, there is a good chance that the old code was faulty as well, just unnoticeably so. You just didn't realized the bugs were there. Turn on the light and the small feet run to the little holes at the side of the floor. Software bugs are not cockroaches. If you turn on the light they can be seen. Write unit tests. Write tons of unit tests and spend time thinking about how your code could look better. It will pay in the long run: the customer will pay for it, but on the other hand the customer will also get the value. Then you will no longer face the question should it be readable or should it work?
Until the next project starts …