We live in a world where software runs everything—from TVs to iPads, washing machines to microwaves, smartphones to IoT devices—you get the idea. It takes several million lines of code to run software and execute specific tasks. Coding is not a one-time thing; it’s an iterative process where the programmers are required to make continuous improvements in the code, add new features, and so on. With the increase in code complexity, it becomes essential to follow clean code practices. We’ll go through just that in this blog! I’ve used Rober Cecil Martin’s aka Uncle Bob’s “Clean Code” as a reference for this post. I highly recommend this book to anyone looking for software developer jobs.
The clean code practices apply to all programming languages. For demonstration purposes, we’ve used Golang in this post. If you are more familiar with Java, please refer to the examples given in the book.
Let’s get started!
The primary purpose of comments is to explain the code which can’t explain itself. Comments are pretty helpful in debugging and analyzing code, troubleshooting errors, and preparing documentation. They come in handy when a new team replaces the old one and gets to work on the existing code.
A rule to follow: A comment only needs to exist if it’s beneficial
Additionally, you need to be careful while writing commentaries. Some types of comments that one needs to avoid are:
Now, this comment is harmless but clearly out of context. The version control system should handle author information, creation, and update dates, not the code itself. Failure to do so will increase useless lines of code in the program and certainly cause the following problem.
Here’s the thing: your commentary will become outdated at some point in time.
So not just header comments like the above example, but even comments like this one can be problematic:
When the comment shown above was added, the function only received an Id, name, and phone number, but now it expects an address too! You should avoid these kinds of outdated comments, which can be misleading at all costs.
Poorly written and redundant commentaries:
When the code is self-explanatory, comments like the one below are redundant. They just add useless lines of code and force developers to read what they don’t need to:
When writing comments, always ask yourself: “Are they essential?” If they are, write them as clearly as possible. Remember, the comment should help you, not cause confusion.
At times, we add an entire block of code as a comment thinking that we may use it in the future.
However, most of the time, these commented codes are never used. And so, it’s best to avoid writing comments like the one in this image.
Think about it: If that piece of code were so important, it wouldn’t be a comment, right?
To write clean and readable code, one should define meaningful names for variables, functions, classes, interfaces, etc. Furthermore, the name of a function, class, or variable should justify its existence and importance in the code. Simply put, good names are investments that we make to improve the code quality.
Take a look at this example:
It might take a while to understand that this is a median function.
Now, take a look at the same example with well-picked names:
Meaningful names like the ones above make the code readable, understandable, and clean.
Following a project convention is a good practice for choosing names. For example, if you have defined a function that deals with a user object, don’t create function names like:
Using GetMemberName instead of GetUserName will just confuse the readers. So, be very mindful while you decide the names of the elements in your code.
Names should clearly describe what a variable is or what a function does. And so, avoid using ambiguous names, like this one:
Ok, but renaming what? It’s better to create big names instead of short ones, but ambiguous. So it would be better to create something like:
Names should clearly define the action and the purpose of the element, for example:
This function is not just detaching a User from an Account but is also deleting the User. A better name for this would be DetachUserAndRemove().
Functions play an essential role in the world of programming. As a result, these functions have gained more traction with functional languages such as Elixir, Scala, Kotlin, Swift, Haskell, Golang, etc.
Almost every programmer knows the basics of functions. However, here are a few pointers that will help you write cleaner and better functions:
Have you ever seen a function with hundreds and thousands of lines?
A function should be short enough to help the reader understand its purpose at first glance. But how short should it be? We won’t impose some magic number of lines here, but if your function consists of more than 20 lines of code, try refactoring into a smaller one.
One practical way to shrink your functions is to avoid adding logic into if, else, while indentations. Here’s an example:
The function name shows that it prints prime numbers between two arbitrary numbers. Here’s what you can do to make the function more readable and understandable:
This function is easier to understand than the earlier one.
We removed the logic inside the “if and for loops” and defined them separately in other functions, making them more concise. Here are those functions:
Note: Take a look at the order of the functions. When you are decomposing the function responsibility, the reader of your code must read it as quickly as a journal or a story. So try to maintain a top-to-bottom readability of the code.
A critical concept in functions is the single-responsibility principle (SRP). This concept is the first principle of the SOLID principles in OOP. It states that each function should have one single responsibility, which must be well-defined and executed.
Take this example:
This function has more than one responsibility. Hence, it is best to refactor the code when a single function is responsible for multiple tasks.
A function with a lot of parameters is difficult to understand. Here’s why:
These kinds of functions make the code reviewing process time-consuming and messy.
To prevent this, you need to ensure that you use a limited number of parameters that clearly define the objective of the function.
Note: Use the same idea to deal with return arguments.
A clean code has various benefits. First, it helps in performing code reviews efficiently. That way, your peers can understand the code, flow of data, and underlying logic with minimal effort. In addition to this, new joiners can easily understand the old code, making their onboarding process smoother. A messy code might take a developer months to add a new feature or fix a bug. However, a clean code makes the process a lot smoother. And thus, a clean code can save a lot of time, money, and resources!
Do you want to apply to remote US software jobs from the comfort of your home? If yes, Turing may be able to help you very quickly. Visit our Jobs page to know more!
Join a network of the world's best developers and get long-term remote software jobs with better compensation and career growth.