Brett Schuchert wrote a fine article yesterday on the subject of refactoring, or cleaning up your code. And though I agree with most of his arguments against junk code (or what he calls "bit rot") I believe it is time for someone to stand up in defense of millions of developers who cannot seem to get around to clean up their act, or their code.
Rejuvenate Your Code Brett compares software systems with the human body. His argument is that most cells in the human body are replaced periodically, so why don’t we keep rejuvenating our code? Brett argues that humans have to sleep, exercise and eat healthy food to stay in shape. And programmers –who are often not the first to care about the shape of their body– should pay more attention to regular health and fitness processes that would keep their code in good shape.
Now, I’m not going to argue with this using simple arguments like "lack of funding" or "lack of time". These issues can be solved with proper time management and customer expectation management practices. I am more interested in the intrinsic problems of refactoring processes. And here’s what I think:
Brett Schuchert has the analogy all wrong!
Most Software Doesn’t Grow, It Evolves You cannot compare the life cycle of software systems with the life cycle of a human body, because human bodies don’t evolve. I wouldn’t mind if my body could evolve better eye sight, a faster brain, or any of the enlargements promised to me in the email I receive daily. But alas, such improvements are out of my reach. The human body is static, with only minor parts being renewed. It grows, but it is not improved.
It might be better to compare software systems with the human genome, not the human body. The genome of the human species has been written and updated by nature over a period of 6 million years.
Has the human genome ever been refactored? Hell no!
Junk DNA and Junk Code Almost 90% of the human genome consists of Junk DNA. It serves no purpose. It contains repetitive genes for redundancy, parasitic and viral genes, genes that seem to have lost their function, and genes that might simply be a basis for further evolution. There is no biological process to remove junk DNA out of the human genome. And why should there be? What harm is there in having a bloated genome? Human beings seem to function fine, thank you very much. Obviously, nature has decided that the cost of removing junk DNA, and the cost of the minor inconveniences of carrying it around, do not weigh up against the benefits of having it readily available.
Likewise, most software systems in this world contain a lot of Junk Code. They contain repetitive code for redundancy, parasitic code (bad and useless code attached to good code and being copied around with it), old code that has lost its function, and unfinished code that might someday be the basis for further evolution. What reason is there to remove all this junk out of your software systems? Your systems are doing fine, are they not? Then what harm is there in having a bloated code base? Has anyone actually proven that the cost of continuously removing junk code from software systems saves us more than it costs us to keep carrying it around?
Nipples, Teeth and Eyes Male nipples have no use, but nature has decided against refactoring the male nipple out of our DNA. It’s simply not worth the trouble. (And I know some men who are glad it turned out this way.) So why remove code that serves no purpose, when it’s not in the way?
But junk code can be harmful, I hear you say. Well, sure. We don’t need wisdom teeth either, and they can be harmful. Having a smaller, weaker jaw allowed us to grow larger brains, but it has left less room for molars. And the consequences can sometimes be fatal! But apparently, it is even more trouble to cut the wisdom teeth from our DNA. If your code sometimes gives you trouble, are you prepared to go through the pain of refactoring it? Have you estimated if this is really going to cost you less than the trouble of keeping the bad code around for another hundred years?
But some designs are bad, and should be improved before anything else is built on top of it, I hear you say. Well maybe, but maybe not. Our vertebrate eye has a blind spot where the wiring goes through the retina. It is a bad but workable design. And nature has decided to let us keep our inferior eyes, while other animals got much better ones. Do we care? I don’t. I’m more envious of dogs being able to reach lots of places with their own tongue. But the human spine doesn’t allow for that. Scientists agree that the spine is one of the worst designs of the human body. I agree. (And I question the scientists’ hidden motivations.)
Don’t Fix It "If it ain’t broke, don’t fix it," is what people sometimes used to say, before the refactoring hype took over. There’s a lot of common sense in refactoring. Yes, I sleep regularly, I do work out (occasionally), and I eat healthy food (sometimes). But I believe a lot of people’s refactoring efforts fly in the face of that other well-known agile principle: defer decisions. If you don’t have to add a new feature, then don’t. If you don’t have to fix a bug that nobody notices, then don’t. If you don’t have to remove junk code that doesn’t harm you, then don’t.
All problems will disappear, if you wait long enough.
This has been a favorite phrase of mine for years. I tend to postpone activities when nobody really needs them done. There is a good chance that problems cease to be a problem, if you give it some time. I was happy not to have replaced a bad bicycle saddle with a new one, before my bike was stolen a week later. And I am quite happy not to have spent time on refactoring code in a troublesome system that was taken out of production for unrelated business reasons a short while later.
It appears that I’m not the only one who cannot be bothered to tune my code to near perfection. Just run FxCop on any of the .NET assemblies and you will be presented with many thousands of warnings and even critical errors. I guess the Microsoft developers had other priorities as well. Refactoring their code to conform to Microsoft’s own coding standards was, apparently, the least of their problems.
The idea behind refactoring sounds good. On paper. But most software systems evolve. They don’t just grow. And there’s a difference. Evolving systems change their purpose. Growing systems simply renew themselves. Refactoring is a sound idea for growing systems. But for evolving systems you have to take two things into account:
The effort of refactoring code might cost you more in the short term than it will gain you in the long term. Don’t expect improvements to pay back for themselves. Many of them won’t.
Cleaning up code will not only prevent your junk from doing any harm. It will also prevent you from enjoying any (often unexpected) benefits in the near future.