Every developer has spent time working on at least one project that was rife with poorly or bizarrely-named variables/methods/types, dead code, impossibly long code blocks, misleading comments, contorted logic, ancient libraries and dependencies that are never upgraded, and worse.
“Someday,” of course, “we’ll clean that up” — but there are urgent features already promised to customers, urgent bugs, and of course everything is always running late because the codebase is so darn hard to work with.
So yeah, curse the earlier developers who made the first mistakes, right?
Well, the first implementation of anything is half proof-of-concept and usually rushed, and no one ever knows at the beginning of the project how to design for its entire lifespan. And the later developers needed to get these features added ASAP, these bugs fixed ..and after a while, trying to clean things up is an act of recklessness. Everyone is leery of changing code they don’t understand, so they tiptoe around adding in redundant code, touching only what they must, and not even updating comments (what are you going to write? “this does a bunch of weird stuff but at least line 2038 no longer crashes on nulls”?).
Methods sprawl into hundreds or thousands of lines (and have less & less connection to their original names).
Logic gets stranger (because it’s safer not to touch what’s already there… just sort of sneak in the new bit however you can).
Spaghetti code snowballs. (insert horrifying sound-effect here)
Notice that this doesn’t require incompetent developers at any point. If they aren’t somehow getting time to actively maintain the quality of the codebase, it will go straight to hell all by itself. It’s a natural process.
Let’s get to a more interesting insight I had into this whole mess, though. It’s a hell of a lot easier to fix a problem if you can explain it quickly without resorting to technical lingo.
Your codebase is a user interface.
A really, really important user interface.
Your paying customers don’t see it, and your CEO probably doesn’t see much of it, so it gets short shrift. But to the developers, this is the front end of the product. They are working with it directly for hours on end, every day. Every flaw is a distraction, an annoyance, and a frustrating roadblock to getting their job done.
Imagine an email client where your deleted and draft messages are mixed in with sent messages, a random line of text from the current email (or an adjacent email) is displayed in place of the subject, and any time you send an email you have to first be sure that it doesn’t contain more than 5 words that match another email, or that one will be sent as well to the same recipient. Your Edit menu is called “View”, and has three “Select all” items (#2 is “Selcet all”); the first selects text in an email you have previous marked with a content submenu called “Prepare for edit”, the second pops up an error dialog that reads “Text selected succesfully!”, and the third causes a crash. This sounds ridiculous; it is. It’s not far-fetched when it comes to how poor a codebase can become, though.
So if the developers are at all important to the success of your project (uh…), it’s worth some amount of money and time to make sure they aren’t forced to work with a painfully bad UI.
What do customers do when they don’t like the horrible user interface of your product? They switch to a better product, if they can.
Developers do the same — of course, some of them will be “locked in” to the horrible codebase (like customers can get locked in to products they hate…) because they don’t have the skills, confidence, time, contacts, etc. to find a better job, but they’d be happier (and far more productive) if they could work on a better codebase. The developers who won’t be locked in are the ones who are clever, easy to work with, and have plenty of other interesting options waiting for them.
(So yeah, those are the ones you’ll lose. Unfortunately, they’re also the ones most capable of getting you back onto the right track.)
So we’ve carved out some time — how do we actually fix things?
This post is long enough already, so for now I’ll just wave my hands around now and mutter things about building a safety net with automated tests, brainstorming for changes you can do a little bit at a time (and prioritizing them), divide and conquer….
But I do think if we start talking about a codebase as a user interface — thinking of it in those terms — that makes it possible to have people who are known experts in the field, who are masters at organizing and naming things, slicing and dicing and putting things where they can be found when they’re needed. Because some effort is better than none, but it’s not at all easy to do well. “Naming things” is one of the only two hard things in computer science, after all, so if you have solid experience at actually doing this, there should be a line you can put on your CV (and something you can discuss with a manager types) that will make them jump up out of their chairs and rush over to shake your hand.
Share your thoughts — how do you grapple with decaying code? How do you wrestle it back into usability? How do you convince the powers-that-be to dedicate resources to refactoring?