Categories
Uncategorized

When Code Stinks: Smelly vs Clean Code

Most people who have written code know how easy it is to code yourself into a corner. Writing smelly code, or code that is potentially problematic, can make code difficult to follow, maintain, develop, or even make the code unreadable to other programmers. To learn more about code smells, I read an article discussing clean code as well as an article discussing code smells.

Clean Code

The first article, “What is Clean Code?” by Codacy, introduces the topic of clean code and notes nine primary principles of clean code [1]:

  1. Avoid Hard-Coded Numbers
  2. Use Meaningful and Descriptive Names
  3. Use Comments Sparingly, and When You Do, Make Them Meaningful
  4. Write Short Functions That Only Do One Thing
  5. Follow the DRY (Don’t Repeat Yourself) Principle and Avoid Duplicating Code or Logic
  6. Follow Established Code-Writing Standards
  7. Encapsulate Nested Conditionals into Functions
  8. Refactor Continuously
  9. Use Version Control.

While I was familiar with the basics of clean code, reading through the article reminded me that there are some clean code practices I perform better than others. Of the nine principles discussed in the article, one aspect I could use improvement with would be the sixth principle, following established code-writing standards [1]. While I always strive to write clean and readable code, as I switch between different languages I don’t typically reference different language style guides as I ought to. Instead I would write the code with a general eye on consistency and readability, but not necessarily following the language’s style guide.

The Codacy article notes a few examples of differences between style guides between different languages, noting that Java uses camelCase for variable, function and class names, while Python uses snake_case [1]. I tend to avoid snake_case due to personal preference, but it would benefit my code to be consistent with other code in the same language. It would make my code more usable for other developers if I followed language-specific style guides, so I will be more cognizant of this in the future, as I want my code to be usable and useful to others.

Code Smells

The second article, “31 Code Smells…” by Pragmatic Ways, discussed different code smells, how to identify them, and how to avoid them [2]. This article separates code smells into a few general categories: dispensables, bloaters, abusers, couplers, preventers, and other notable mentions [2].

During my time of writing code I have certainly written some smelly code, especially on earlier personal projects. I recall one personal project where I attempted to create an application but did not really plan my approach, and I ended up with extremely bloated code. One of the biggest indicators that I needed to refactor was the long parameter lists (#9 on the list of 31 code smells) for various functions [2]. The article discusses two likely problems that could cause long parameter lists [2]:

  1. There’s more than one thing happening in the function
  2. The parameters are tightly related and should be grouped together in a data object

In this case, it was likely a case of both factors, but certainly utilizing a data object would have reduced the number of parameters passed between functions.  Not only did the excess parameters make maintaining the code almost impossible, but it made the prospect of refactoring overwhelming, and I did not end up maintaining the project. If I were to reapproach it now, I would likely start from scratch rather than clean up the smelly code.

The article’s example code includes multiple parameters which each reference an aspect of a person [2]:

public void printPerson(String firstName, String lastName, String middleName, String maidenName, String babyName, String nickName, String thirdFavoriteDinosaur) {
...
}

This could be refactored to a data object to allow the number of parameters passed to be reduced, as well as generally make the code cleaner and more readable. Consider a Person object which contains the attributes passed as parameters, such as person.firstName, person.lastName, etc. This would clean up the code by organizing the data better and reducing the number of parameters to be passed around, as seen in the article’s solution code [2]:

public void printPerson(Person person) {
...
}

While my personal example was from quite a while ago, there is still the possibility that similar code smells could find their way into code that I write. To avoid repeating the code smell of excessive parameter lists, I will note when parameters are linked and ought to be encapsulated in a data object, as well as assessing if my functions are targeted enough.

By keeping an eye out for code smells as I write code, as well as reassessing previous code I encounter, I will be better able to keep the smells at bay and write cleaner code. Unaddressed code smells can snowball into an unmanageable situation which could significantly hinder development of a project.

Sources

[1] Codacy, “What Is Clean Code? A Guide to Principles and Best Practices,” blog.codacy.com, Dec. 19, 2023. https://blog.codacy.com/what-is-clean-code (accessed Jan. 16, 2025).

[2] A. Allard, “31 Code Smells all software engineers must watch out for,” Pragmatic Ways. https://pragmaticways.com/31-code-smells-you-must-know/ (accessed Jan. 16, 2025).