Messy code

Sep 11, 2017

Have you ever looked at a piece of code and thought how awful it is? Codebases tend to get messy with time. And don't have illusions: this is true for your code too.

Why is that?

The #1 cause is the changes in the specification. When new features are added, they need to be fit into the architecture. When enough of them are in, these retrofittings accumulate. Messiness usually correlates well with the number of off-the-architecture features inside the code.

When you start building a system from the ground-up, you get a specification. Either in written ("it's rock solid and won't change") or verbal ("these are the general guidelines") form. You devise the architecture that fits all the requirements known at that point. Then code away, and a relatively clean codebase emerges after some time.

But software is not like a skyscraper which you build once and stays pretty much the same for a century. Usually, before development reaches the end of the initial specs, requirements change. And this wreaks havoc to the clean codebase.

An architecture is already in place that is fine-tuned to the original specs. Now the new features need to fit into this framework. And by the very nature of changes, they most likely won't. A small hack here and there, and by the time the version reaches 1.0, there are already several corners cut.

When I look into codebases, I usually start to wonder why someone did something in a particular way, as that solution does not seem to fit into the architecture. Or parts of the program appear to stand out from the rest of the codebase. In other cases, the architecture itself is so patched-up it's hard to imagine someone deliberately made it this way.

The answer is usually the changes in the requirements. Back then, for that specification, it is likely that code was a near-perfect fit. Then things changed, and people introduced patches to make it float. In any single point of time, the codebase can be made better with a complete rewrite, taking account the accumulated knowledge what it should be. That doesn't mean you should constantly rewrite everything, just be aware that your current knowledge of the system and the domain is greater than what it was when the code was initially written.

Is this messiness a problem?

Yes, but it's not something you can do much about. If requirements were solid and frozen, that would mean the company could not respond to changes. You might have a perfectly clean software, but a broken business. Instead, accept the continual nature of refactorings.


Code gets messy by the number of hacks that accumulate over time. These are usually caused by changes in requirements that do not fit into the original architecture. Accept that the original developer (be it yourself or someone else) was not completely incompetent, but lacked the knowledge of the changes you know today.

Changes occur. You can not freeze requirements, as that would kill the business.

Embrace the idea that you can not stop working on the architecture along with the new features. Software development is an evolutionary process that requires constant work.

The code you write today is the legacy mess of tomorrow. But that's ok.