Wednesday, December 07, 2005
To Fix Or Not To Fix
Whenever I have to modify some code, I like to leave it better than I found it. In the wild, one finds a lot of "bad code." That's not because the people who wrote it were stupid or careless; we programmers just never have enough time to do things as well as we'd like. So there is always room for improvement, and I improve whenever I can. There are always poorly named variables and subroutines that can be renamed, expressions that can be simplified, methods that can be extracted, dead code to be removed, boundary conditions to be considered, and comments to be added (or updated or deleted).
However, some code is so screwed up that you can't improve it. It's so complicated that you can't tease it apart without fear that you will make it worse. Without automated tests, you can't verify that the "improved" version does exactly what the old version does. Without talking to the original programmmers (who left the company years ago), you can't figure out why they did it they way they did, so you don't know if there is some subtle problem that requires the strange implementation they chose.
I always feel guilty when I leave bad code as-is. I always think that the reason it is bad is because people like me are afraid to touch it. If somebody doesn't dive in and do the hard work, it will never get better. When I refuse to try to fix it, I'm part of the problem.
In such situations, I console myself with the rule that one should "first, do no harm." Maybe I'm not making it better, but at least I'm not making it worse. But that isn't much consolation. If I'm making changes around the bad code, without touching the bad code, I probably am making things worse. I'm just adding hacks on top of hacks. I'm just making the next programmer's job harder, because that programmer will not only have to figure out why I did what I did, but also figure out why I left the god-awful stuff around it alone.
An important step in the maturity of a programmer is the stage where the programmer is no longer afraid to change other peoples' code. Extreme Programming (XP) holds Courage as one of its core values. Discovering "this is bad, but I know how to make it better" is the one thing I enjoy about maintaining legacy code. Unfortunately, my courage often falters, usually because of an approaching deadline.
And when one does the right thing, and spends a couple of days turning an incomprehensible mess into beautiful, verifiably correct code, there is no appreciation. Management considers such activity to be a waste of time. Other programmers will nitpick, or make fun of you for being one of those design patterns cultists.
I'd like to have some simple rules to follow when conducting the triage of determining whether some bad code is best left as-is, or should be fixed, or should be thrown away. But this is one of those "hard problems" that comes with being a software engineer. You have to guess, and you will never know whether you were right.
I see a lot of old guidance, regulations, and policy (which I call the 'source code of government'). For example, I'm familiar with a 57-some-odd-step-process that takes 6 pages to correctly flow chart. It's a beast.
Recently, I talked to someone who has mastered the process. He doesn't feel comfortable enough to change it, because he doesn't know _why_ each step exists. Parts of the process are required by law, parts by regulation, parts by executive order, parts just created by CYA bureaucrats.
Without doing a line-by-line condordance (which no one wants to do), the process will never get teased apart and fixed. I wish I could get assigned to the process improvement team because I would _love_ that gig.
Regarding the Latvian Forth Princess... she doesn't exist. Sorry.