DEV Community

Cover image for Code Quality is a Lie
Timothy Ecklund
Timothy Ecklund

Posted on

Code Quality is a Lie

The phrase "Code Quality" makes me extremely uncomfortable. That phrase gets thrown about frequently and causally, but it is so vague that it's useless at best. At worst it's merely a verbal cudgel to beat someone else down. The phrase is synonymous with "I like that code" or "I don't like that code." (Sometimes it's even synonymous with "I don't like the author of that code.")

But as a metric, that you "like it" is not a measure of somethings quality.

It gets worse. Not only is that phrase ridiculously vague, it also implies that code can be judged against some universal metric - that there is a knowable and linear scale. Some code is simply "better" than other code and you know how to tell the difference.

This is nonsense. A thing can not be "better" or "worse" than another thing in and of itself - it can only be better or worse at something. Let's consider a story of two toasters.

Toaster A costs $15. It has no settings and no manual. It plugs into the wall, you put in the toast and you get the same exact level of toasting out of it every time. Its slots are only wide enough for bread so don't bother with bagels.

Toaster B costs $40. It has a very detailed and thick manual, describing how to maintain and service this toaster. It has extra wide slots for bagels, and a wide variety of settings. It also plays a cheery tune when it's done toasting.

So, which of these toasters is of higher quality? The answer is obvious - neither of them. They have different properties, and those properties come with costs. Which set of properties and costs is appropriate and preferable for you depends on your circumstances.

"Quality" does not exist independent of what your requirements are, and therefore "quality" does not exist, only contextual preference. Toaster A might suit your needs very well, and you might appreciate its durability given how few things there are that might break. Toaster B might be more appropriate for the toast or bagel enthusiast, someone who doesn't mind soldering on new heating elements as the manual suggests.

But Tim, you might object - what if Toaster A and Toaster B had exactly the same features and costs, but Toaster A lasted 50% longer before wearing out? Wouldn't Toaster A be of higher quality?

No. Toaster A has the property of durability, and assuming durability is one of your requirements (maybe you don't care!) then it's fair to say Toaster A is preferable. However, that is only because we care about durability - if we didn't, then we would have no preference.

But Tim, you might object - What if Toaster A and Toaster B are outwardly identical. They have the same observable properties, like features and durability, but Toaster A is made cleanly and simply while Toaster B is convoluted and complex inside. Wouldn't Toaster A be of higher quality?

No. If they have the same observable properties then neither is preferable. There is no magical substance, "Quality-O" that suffuses one and not the other. If one lasts longer or is easier to maintain then those are observable properties - assuming we someday observe them. It's entirely possible that the toaster lives its entire useful life without needing to be serviced. In that case, there were no observable difference and they were equally preferable.

Ah-ha, you might say. But if Toaster A is simpler then it is less likely to break. Your pedantry avails you nothing. The word "quality" is merely a shorthand for how likely something is to fail to meet our requirements. We say "high quality" when we mean "likely to meet our expectations and needs" and "low quality" when we mean "likely to disappoint us." It might be imprecise, but it's useful.

On that, I wish I could agree with you. If the phrase "Code Quality" were used thoughtfully, with the understanding that it was a shorthand for "the properties of this code lead me to believe that it will or will not suit the requirements or business need" then I would not be writing this post.

But even if that were true, "I believe this code won't meet our needs" is still extremely vague. Why won't it meet our needs? What about it exactly is problematic, why are those problems important to the business, and what metric do you expect would change if we did it your way?

If you have a hard time answering those questions, then your shorthand is not useful - it is sophistry.

This leaves us with a couple of problems. First, it challenges us to think through what exactly we mean by "quality" in a different light. Second, if we can't say "quality" then what shorthand can we use to talk about our contextual preferences?

Let's address the usual suspects that people bring up under the umbrella of "quality." When you look at a piece of code and judge it, what exactly are you thinking about?

  • If you think it needs more tests, why? Are you having a problem with bugs on release?
  • If you think it needs more documentation, why? Do you have people who need to understand it but can't? What cost are you willing to pay for more documentation?
  • If you think it needs to be faster, why? What business requirement are you meeting by improving latency? Is the dev time worth the reduction in latency?
  • If you think it needs to be simpler, why? Are you changing this code frequently, so the complexity is hindering your velocity?
  • If you think it is insecure, why? Is this public facing? What breaches are you concerned with and what business impact would they have?

Whatever metric you are using, unless it is tied to a specific and business oriented metric then it is vanity.

Alright, let's say for a moment that you've gone through the exercise of orienting your priorities and assessing your contextual preference about some code. It lacks tests, and so it breaks frequently on release, causing headaches for the business. It is overly complex, so changing it takes too long, and the business is suffering for it. On and on, you have nailed down the issues. You have also come up with solutions to those issues, and let's say that your solutions are good ones (fingers crossed).

When talking to someone else, especially someone non-technical, how do you communicate that your code is, or will be, better for the business? How do you communicate the extent to which it will be "better"? It's a tough one, because it's a lot of nuanced information, and usually it's too much information.

I don't have a perfect answer. There isn't a one size fits all solution, communication is a hard thing to do. I will say this however - the exercise will make you a better engineer. Forcing yourself to choose the right metrics, and to judge something against those metrics will make you more thoughtful, slower to judge, and ultimately much more effective.

Then when someone asks you if a codebase is of good quality, you can confidently say, "Maybe. It depends."

Top comments (4)

Collapse
 
moopet profile image
Ben Sinclair

I disagree.

In my example, two codebases (or toasters, I guess) are outwardly identical. They all pass the same tests, or meet the same acceptance criteria so the end user sees them as equivalent, but one has something that makes people complain about its "quality".

Let's say it's that the author has used funky variable names like x, k and thingy. If the code is never updated in the future, that's fine, I guess, but the implication is that the developer will do that on their next project where it'll suddenly be important.

You're hoping that nobody else will ever have to maintain it, and saying that's not part of the requirements isn't good enough to give it a free pass, to my mind.

Collapse
 
gnomff_65 profile image
Timothy Ecklund

Can you expand on what you mean by "something that makes people complain about its quality?"

Also, my point is not that maintainability isn't important, only that it's important in a specific context - the context where it needs to be maintained. We make our code maintainable because we think it will need to be maintained, and 99% of the time that's a good thing. The point that I'm making is that we should make these tradeoffs thoughtfully, not that we shouldn't make tradeoffs at all.

Collapse
 
moopet profile image
Ben Sinclair

That's true, but the cases where we think it doesn't need to be maintained it will probably end up being maintained - or it's some kind of throwaway application for a one-off job.

The thing is, if you say you can write "bad" code for things you don't care about, and it's ok, why would you? You're essentially practising two different styles of coding for the sake of a short-term win, and that's probably more brainworking than if you wrote it all the same in the first place.

Thread Thread
 
gnomff_65 profile image
Timothy Ecklund

I think we're arguing different things. I'm not saying it's all cool to write "bad" code. I'm saying, what is the definition of "bad?" Why is writing code with this heuristic better than another heuristic? What implicit tradeoffs are we making when choosing one set of properties over another?

Personally I try to write code that is testable, maintainable (via composition) and with plenty of descriptive comments, because those are the things that I have chosen to care about. But when coming into someone else's codebase, it's not helpful to say "this is low quality." That word is so vague that it loses all meaning. The code has a certain set of properties, like testability or complexity, and when talking about improving it we need to be precise in our language or we're just saying "this is bad, you're bad, I know better than you."