8 Code Smells
Good code != code that performs the required functionality
Sometimes code works as it’s supposed to, but it just doesn’t smell right.
We all know that smell is subjective, and code smells are no different. I have my personal pet peeves and I’m sure you have yours. I’m going to touch on a couple of things in code that smell bad to me…. and how to improve their smell.
I’ll start off with five obvious ones and I’ll end with three of my favorites. Some of these might seem almost too obvious, but I still want to mention them since I tend to come across them in PRs quite often.
1) Repeating code
Are you repeating several lines of the same, or similar, code in the same class?
Make a function for it.
We all know it. Just do it.
Sidebar: when to fix?
Code smells should be fixed during coding.
Refactor your code as you are writing code.
As soon as you smell one of these odors: rectify!
2) Repeating functions
Do you need the same functionality in multiple classes? Write a function in a helper or a service class.
What’s the difference between a helper and a service class? Here’s my definition:
- Helper class: Generic functionality that could be used by different classes.
- Service class: Functionality specific to a certain part of your business logic.
3) Repeating strings
Do not repeat string literals in code. Make it a const!
Are you using string literals in multiple classes? Define them in a helper or service class. Otherwise just define them in the class where they are used.
4) Large functions
Function getting too big? Split it into multiple functions.
What is too big? Your function is probably too big if you have to ask.
5) Large classes
Split large classes into multiple classes.
It’s very daunting to try and understand a large class. Multiple small classes are much easier to understand and comprehend.
6) Comments in the middle of a function
Your code needs comment blocks to explain what it does? Make it a function!
Too many comment blocks in the middle of your code make it harder to read. Use functions as a form of comment.
7) If-else statements
A lot of if-else statements can be rewritten as an if statement, without the else. How? By using negative logic.
Why is this better? Because I have to remember less when I’m reading this code.
By the time I get to the else statement I still have to remember what the if statement was about. If I don’t remember I have to jump back to see what the else exactly means in this context.
When I use negative logic, you can forget the earlier code when you are reading the second code block. As soon as I pass the if statement block I can forget the context and move on to focusing on the next few lines of code.
I much prefer being allowed to forget information over having to remember x levels of context.
8) Nested if statements
This one is very similar to the last one.
Adding a return statement inside an if block is a good way to get rid of nested if-else statements.
The code block on the right is much easier to read than the code block on the left. Why? Because I don’t have to remember any context. I can forget the previous line as soon as I pass an if statement’s closing brace.