What is Clean Code, and Why is it Crucial to Quality Software Development?
Facundo Revello
May 6, 2020
Many developers have heard of clean code or even use clean code every day, sometimes without actually knowing much about it. In this post, we’ll explain what clean code is, why it should be used, and why it's a good habit to incorporate. If you're already familiar with clean code, this post will help you review the main concepts; if you are new to the idea of clean code, by the end of this post you will understand the benefit of writing clean code and learn about how it's done.
What is Clean Code?
Before going for a deep dive into clean code, we have to mention Robert C. Martin (known as Uncle Bob), a well known software engineer, co- author of the Agile Manifesto, and contributor to the development of the SOLID principles. Uncle Bob is the author of Clean Code: A Handbook of Agile Software Craftsmanship, a highly influential book that has changed how code is written.
Clean Code is a guide on how to write elegant, efficient, easy-to-read code. We are going to cover the most important guidelines, but we also recommend reading the book, as it covers more topics and goes more in depth than we are able to in this post.
Names, Comments, and Formatting
It might sound trivial, but names, comments, and formatting are important aspects that allow the code to be more readable and more easily understood by any developer.
When declaring new attributes, functions, or methods, the name plays a key role. Choosing a name that is meaningful and can explain itself improves our code. We should avoid hard-to-read names and names that don't mean anything or aren't relevant to the purpose of the attribute, function, or method. Choosing the correct name will also improve the possibility of searching and locating these names in the code.
If the naming is done right, it should prevent us from using comments. Comments should be avoided if possible, as they can be harmful if not used properly. Comments are hard to maintain because if the code changes, the comments must be manually updated. If the comments are not updated, it may lead to confusion and unnecessary problems. Informative, legal, or clarifying comments can be made if they help the code be more readable, but as a general rule comments should be used as little as possible. If the code is clean, comments won't be necessary.
Formatting the code may seem unimportant, but it is a key aspect when creating professional and readable code. Files should have a maximum length of code lines, and each file should not have more than 500 lines if possible. In addition, the code should have a maximum of 100 to 120 characters horizontally. As code is read from top to bottom and left to right, the code should be indented using the conventions of hierarchical order.
Functions
One of the most important rules when creating functions is to make them small. Long functions are hard to read and understand, so we should keep it simple and short. If we have a function of more than 20 lines of code, we should try to split it into multiple shorter functions that are easier to read.
Another key aspect of functions is that they should do one thing and one thing only. There are multiple ways of knowing whether a function is doing only one thing, but as a general rule, if the function has more than one level of abstraction, it is doing more than one thing. We should keep it to one level of abstraction and avoid mixing levels of abstraction within the function.
There are other many aspects we should consider when writing functions, such as the number of arguments a function should use. When we are planning a function, we should take into account that no more than three arguments should be used. Ideally this number should be as close to zero as possible, as this will reduce the complexity of the functions and make it easier to test. Less arguments mean fewer tests, as there are fewer combinations of tests to make. Finally, functions should do what they are supposed to; this might sound a bit redundant, but it is important to ensure that using a function doesn’t have any undesired side effects or unexpected behavior.
Objects and Data Structures
A key aspect of clean code is to hide implementation behind abstraction. When creating classes, we should try to hide the implementation by using abstract interfaces to avoid any dependencies between sections of the code. Using getter and setter methods to obtain variables directly on classes is not a good idea. Interfaces should be used instead, allowing the manipulation of this data regardless of the implementation of those classes. This will save us from unnecessary problems when a new implementation is needed for a class.
Now that we have hidden our implementation, we can now comply with the Law of Demeter. This law states that modules should not know about the internal structure of the objects it manipulates. As a general rule, objects should expose behavior and hide data, and contrary data structures should expose data and have no significant behavior.
Error Handling and Testing
The clean code approach to error handling involves using exceptions to catch errors rather than using return errors or flags. For example, it is a good practice to use the try-catch in sections of the code that might fail and catch the errors properly. It is important for debugging purposes and better error handling to create error messages that are used by the exceptions, so when an error occurs, enough information about the error is provided so the source can be identified.
Testing is a big part of clean code, and writing proper tests is very important. If possible, it is recommended to use the TDD programming technique so almost a 100% test coverage can be assured. Tests must be maintained so they are not coded separated from the system. If the code changes, the test must be updated.
When writing tests, there are five rules: First, Isolated, Repeatable, Self-validate, Timely (F.I.R.S.T) we must follow to ensure that we have proper and clean tests. As tests must run all the time while programming or be automatically executed after writing the code, the tests must be fast. If the tests are slow, developers may avoid running the test because they take too long. This leads to future problems and bad practices.
When creating a test we have to keep in mind that every test must be independent; no test should depend on another to be able to run. Tests must be executed in all environments, such as development or production. If a test runs in a development environment but can’t run in production, this will lead to bad practices. The result of the test must be easy to read. The best practise is to return a boolean indicating the result of the test, as that will allow the developers to quickly have the results. Finally, it is a good practice to plan and write the tests before the actual code reaches a production environment.
Classes
When we are planning and implementing classes, we need a similar approach as with functions. Classes must be small, and it is important that the name is meaningful, as classes might be used all across our system. Classes should follow the Single Responsibility Principle (SRP). To follow this principle, classes should have only one responsibility and only one reason to change. If a class has many responsibilities, a good practice is to split this class into separate classes.
Why Should We Use Clean Code?
After discussing clean code, we can see that there are several benefits of using it. We are going to review the most important benefits of using clean code principles when writing code.
Cost
The cost it takes to implement a system can be a key issue when acquiring new projects or new clients. It is important to stick to the cost estimations to avoid any unnecessary problems with clients. Developers or managers know that the cost of fixing problems or bugs grows exponentially as the code advances through the different stages of development. Following clean code practices will help us avoid this problem by implementing unit testing, creating tests using F.I.R.S.T, using TDD, etc.
Time
It can be hard for developers to deal with projects or code that they didn’t write or contribute to. Imagine now that you are new to a project and you have to develop a new functionality or fix a bug in a systems. If the code is hard to read, there are no identantions, the names of the classes or methods don't mean anything, you will have to invest more time than you normally would in understanding the code in this new system. If the code follows clean code guidelines, it's easy to read, and it will take developers less time to understand it, implement new functionalities, or fix bugs properly.
Maintainability
The development process doesn’t end when a system reaches production status. There is an significant amount of time and effort we have to invest to keep the system up-to-date so that it can work properly and efficiently. If the code of the system is a mess, we are going to have a hard time detecting which sections of the code must be updated or which dependencies are deprecated.
Ability to Adapt
Systems are not static, and as the business or context changes, the system must have the ability to adapt to those changes and stay relevant to users. We need to make sure that the system we build can change, as change is inevitable, and we need to handle the impact of these changes. If we follow the clean code guidelines on how to implement classes, data structures and objects, we are going to avoid unnecessary work while changing or updating whole sections of the system.
Quality
Many of the aspects we mentioned above will determine if our system meets the quality standards of software development. This is why clean code has become a quality indicator for developers; it helps to achieve the development of better systems.
Making Clean Code a Habit
We have discussed that using clean code practices will benefit your code writing, but how can you make a habit of following these guidelines and incorporate it to your skill set? The first thing will be to know that clean code can not be mastered in one day; it will take time to practice and make a habit of these concepts.
As there are a lot of aspects to take into account, we recommend a few tips. The first thing is to make a small list of all the key concepts, such as writing names, comments, functions, etc. You should keep this list at hand when you write code, so you can check the items at the same time you are writing code. For example, after writing a function you can make a quick check of the function name, the size, whether it is only doing one thing, etc. In addition, after making a pull request you can do a quick check of all the code to verify that you are following these guidelines. After a while, you won't have to keep the list at hand, and you will start coding with these guidelines without having to remind yourself..
Last Thoughts
Developers at sophilabs use clean code guidelines to write our code on a daily basis. This is one of the key aspects that we review when a developer creates a pull request. In our experience, we consider these guidelines the best way to write the best code possible. It is quite common to have new developers to join the team.The onboarding process can be very challenging for them, as they have to learn how all the systems work. However, the use of clean code allows them to understand the code as quickly as possible, and they can start delivering value to the client sooner.
Writing code not only involves making something that will work and that meets expectations, it means making something in the best way possible. With clean code, developers can create systems that are easy to maintain, that can adapt to the changes, that will improve their performance, and that will prevent the waste of resources. Incorporating clean code as a habit is a decision that makes us better developers.
The Benefits of Using TDD
Test-driven development (TDD) is a great way to make sure a product fulfills the client's requirements. In this post, we walk you through the basics of how it works.
How We Do Code Reviews
Thorough code reviews are an important part of how we deliver state-of-the-art web and mobile apps that users love. In this post, we walk through our process step by step.
Photo by Émile Perron.
Categorized under research & learning.Join our team
If you're passionate about building quality software and our values resonate with you, get in touch with us!