Talents en applications - Blogue | Nexapp

Introduction to the World of “Code Smells”

Written by Martin Nadeau | Aug 9, 2022 4:00:00 AM

When we talk about code smells, we're talking about a vast subject on which we could spend years publishing relevant information. Today, I'd like to take you gently into this universe by defining what a code smell is, what it's used for, how to recognize it and give you a few examples. Let's get started!

What's a code smell?

First of all, it's a term coined by Kent Beck while helping Martin Fowler write his book on refactoring. He used the term to describe an element that may indicate unnecessary complexity, making the code evolution more complex.

Code smells are often an indicator, a symptom of a problem rather than the problem itself. They can take different forms, such as readability, duplication or difficulty in writing tests, for example. They can occur in both production and test code.

It's something that tells the developer: this doesn't smell right, I need to analyze it further and try to find the source of the problem so I can fix it.

What's the point of a code smell?

Code smells can help us identify common design problems that are quick to spot. In this way, we can target problems that occur everywhere and at every level of abstraction. What's more, they allow us to identify the refactorings, or combinations of refactorings, that work best to eliminate these "smells".

Indeed, once we understand what a smell is, we're in a position to make links with refactoring techniques to correct them. Identifying smells opens the door to a series of proven solution paths, often patterns that old hands have built up over the years, making problem-solving much simpler.

As developers, it's in our interest to follow this nomenclature and master it, in order to benefit from the intelligence of the community, which is served to us on a silver platter. There's no need to reinvent the wheel every day when you've got a track record of solutions proven in hundreds, if not thousands, of cases!

How to recognize code smells?

To get started, there's no magic formula: you need to read catalogs and practice recognizing them. You can also hold workshops with your team: look at code together and share what you don't like, but above all why you don't like it. Does it have a name? Scratch away. Once you've put a name to the problem, you'll have some ideas for solutions!

In our field, many elements can look like smells because of the complexity of the work done. But real code smells tend to be accidentally complex. As a result, you need to analyze each smell carefully before concluding that there is indeed a problem.

Where can I find catalogs of code smells?

Many code smells catalogs are available online from developer communities. These catalogs provide a rich and colorful vocabulary with which programmers can quickly communicate about design issues. Some categories also exist to show the impact that code smells can have in the long term.

For example, in her presentation Get a Whiff of This, renowned developer Sandi Metz lists some classic code smells, classified in different categories:

  • Bloaters | long method, large class, data clumps, long parameter list, primitive obsession
  • Preventers | divergent change, shotgun surgery, parallel inheritance hierarchies
  • Couplers | feature envy, inappropriate intimacy, message chains, middle man
  • Abusers | switch statements, refused request, alternative classes with different interfaces, temporary fields
  • Dispensables | lazy class, speculative generality, data class, duplicated code

If we take bloaters, for example, these are code smells that pollute code that could be much simpler.

An example of smell code

In codebases that don't use Domain-Driven Design (DDD), where we try to approximate the language of the domain, we commonly find the smell of "primitive obsession", which is part of object-oriented abuse. This can be observed when we directly manipulate the primitives offered by the language, and must always validate the content of these primitives before processing. All this adds complexity, very quickly, and creates a lot of duplication! The various smells and refactoring catalogs will suggest encapsulating validations with primitives in the construction of a new domain concept. You'll be able to put a word on this new concept and assume, when using this new concept, that it contains validated data.

Benefits of code smells

  • Code smells are technology agnostic. They are simply labels associated with potential errors, so anyone can use them!
  • When everyone has a good understanding of smells, they facilitate team communication.
  • They enable proven solutions to be found more quickly.
  • They are linked to the notion of refactoring and facilitate maintenance.

Many developers are reluctant to refactor, for a number of reasons: they prefer to rewrite (a big red flag!), they're afraid of breaking everything, they've always worked that way, they don't have the time (aka it's not valued by the company), they don't know the patterns, techniques or best practices, or they don't know where to start. But often it's simply because we don't recognize the signs that the code is sending us aka, we don't recognize the smells.

The only valid reason for avoiding refactoring, and it's only valid temporarily, is a short-term schedule that forces us to focus on a single thing.

If you're interested in the lexicon of code smells, I suggest you also take a look at the concepts of refactoring, technical debt and Test-Driven Design (TDD). All this is closely linked to keeping your architecture evolving; identifying code smells is the first step!

References and catalogs