If you've been programming for even a little while, you've probably come across the term "code smell". You probably have a good idea of what it means. And you've probably used it on numerous occasions. But I'm here to tell you that it doesn't quite mean what you think it means. Or, at the least, what I hear when someone says "code smell" is probably quite different than what you hear when the same words are uttered.
As a somewhat colloquial term, there's really no official definition for "code smell". So we're gonna start out with the basics - from Wikipedia:
In computer programming, a code smell is any characteristic in the source code of a program that possibly indicates a deeper problem.
OK. So far so good. This definition is probably as useful as any other. But Wikipedia doesn't stop there. The next sentence says:
Determining what is and is not a code smell is subjective, and varies by language, developer, and development methodology.
Hmm... Interesting. Pay keen attention to that word "subjective", cuz that's what I'm about to dive into.
In my experience, "code smell" all-too-often means this:
I can't quantify exactly what I don't like about your code. And I can't be bothered to explain this to a plebian like yourself. But I don't like it. So I'm just gonna dismiss it with the all-encompassing label of "code smell".
Obviously, I don't think this is the "definition" in everyone's mind every time they use the phrase. There are plenty of benign uses of "code smell". I've used the phrase myself. Everyone has. But I've seen too many scenarios where the use of the phrase falls under the definition I've listed just above.
I don't remember anyone ever talking about "code smells" when I started my career. When I read further on Wikipedia, this makes sense. Wikipedia states:
The term was popularised by Kent Beck on WardsWiki in the late 1990s. Usage of the term increased after it was featured in the 1999 book Refactoring: Improving the Design of Existing Code by Martin Fowler.
That actually tracks quite well with my recollection. There was some point in the mid-to-late 2000s when, seemingly out-of-the-blue, I began hearing colleagues shoot down coding examples as "code smells". It was as if the term suddenly materialized in their brain and they seized upon it as a convenient (read: lazy) way to invalidate broad swaths of legacy code.
It's not that I have a problem with the phrase itself. Nor am I bothered with (what I believe to be) its underlying premise. Rather, I quickly became annoyed at the way in which many of my colleagues suddenly felt empowered by the phrase to dismiss other solutions with no further explanation or consideration.
I'd pull up a code sample - maybe something I'd written, maybe not - and before we could even proceed, someone would chirp up that it was a "code smell". And... that was it. Once someone throws out the "code smell" bomb, good luck getting them to rationally consider anything else that they see in that block of code.
Here is just a sampling of the kinds of code I've seen dismissed as a "code smell":
Older Languages - Look, I understand that many people hate PHP. But code should never qualify as a "code smell" merely because it's written in PHP (or any other language).
Older Frameworks - There are billions of lines of jQuery out there in the wild today. They're not going away any time soon. Get over it. If you wanna label every line of jQuery code as a "code smell", you need to ensure that you never ever work in a shop where legacy jQuery code still exists.
Something Other Than Your Favored Paradigm - Maybe every single one of your React components is written with functions and Hooks. If so, then Yay! for you. Go eat a cookie. And try not to sprain your elbow while you're patting yourself on the back. But your religious adherence to functions doesn't meant that a class-based component is a "code smell". It's just... not. Get over yourself.
Competing Coding Styles - There are a million different ways to write the same set of instructions. Your team has probably settled on their preferred coding styles. But that doesn't mean that other styles are "wrong" or "code smells". For example, if you want the old guy to dump his
functionkeywords in favor of all-arrow-functions, all-the-time, then that's fine. Talk to him. Explain the standards on your team. But don't be a jerk by just dismissing any use of the
functionkeyword as a "code smell".
You may be reading this list and thinking that none of these broad examples truly qualify as a "code smell". And you'd be right. I'm just ranting about the fact that I've seen the "code smell" phrase used as a global catch-all for: "code that I don't like and I want to shame my colleagues into abandoning it".
The code smell has an ugly sibling. It's called the anti-pattern. Just like "code smell", there are legitimate times when something should probably be labelled as an "anti-pattern". And just like with "code smell", the phrase is too-often used as a lazy way to discard alternative approaches - without bothering to quantify why those approaches are bad.
I personally find anti-pattern to be particularly affronting. Because a "pattern" is neither right nor wrong. Patterns are "right" when they're used in the "right" scenario. And they're "wrong" when they're used in the "wrong" scenario. But once someone slaps that "anti-pattern" label on your approach, they're basically saying, "This should never be done." The problem with that mindset is that there are very few patterns in programming that should NEVER be used.
Look, I'm not claiming that you should never label something as a "code smell" or an "anti-pattern". I've done it. We all do it. And it's not inherently wrong. But you should be careful that you're not lazily slapping it on things that you don't like. You should always be able to quantify why a particular code sample is a "code smell" or an "anti-pattern". If you can't, then it may not be the code that stinks. It may be you.
[AUTHOR'S FOLLOW-UP: Just today I found this excellent article from several years ago. It really hits to the same points I'm trying to illustrate in this article, and I highly recommend it: https://www.cambiaresearch.com/articles/995518/six-reasons-to-ditch-the-term-code-smell]