As programmers we often talk about “bad” code. But interestingly, I don’t believe I’ve ever heard someone actually define exactly what bad code is.
I find this unfortunate because saying code is “bad” is actually meaningless, especially to a non-technical manager. If a non-technical person hears me say that our code is “bad”, they might believe me, but they won’t understand what it means for the code to be bad or what it would take to make the code good.
If we can put our finger on exactly what we mean when we say “bad code”, maybe it will help us go from sounding like we’re complaining about the code to getting on the path to making the bad code good.
So I’m going to try to define what bad code means.
My definition of bad code
Bad code is code that is risky and/or expensive to change.
Let me break that down.
What does it mean for code to be risky to change?
Have you ever been scared to deploy a code change to production? I have.
What exactly are we afraid of when we’re afraid to deploy a change? Basically, we’re afraid of introducing a regression. If the code we’re working on is hard to understand, then that means we don’t understand the implications of our changes. That means that all the carefulness in the world can’t protect against accidentally breaking some part of the application when we make a change.
Consequently, we cause problems for customers. We cause customers to lose money. We make customers frustrated with our employer’s product. We make everyone trust the development team less. These are all genuinely bad things. If a codebase is sufficiently hard to understand that it poses these risks to the development team, then I would say that that code is bad.
What does it mean for code to be expensive to change?
The cliche that time is money is true. The longer it takes a developer to be able to understand a system, the more expensive that system is to maintain.
In addition to “bad code” another term that gets thrown around to the point of meaninglessness is “maintainability”. We often talk about code being “maintainable” or “unmaintainable” but rarely talk about what exactly that means. Another way to say the same thing would be to say that code has a low cost of maintenance or high cost of maintenance.
This is true of not just code but all parts of a system. If we use unclear variable names, convoluted database schemas, or methods and classes that are too big to quickly and easily grasp, then future maintainers of our system will have to spend more time (which means more money) to be able to understand the system.
The reason I’m talking about understandability is because in order to confidently change code, you first have to understand it to some extent. Have you ever made a one-line change that took literally three seconds to make but then spent 30 minutes studying the code and testing your work because you weren’t sure you understood the implications of your change? The longer that “studying and testing” period, the more expensive the code is to maintain.