Introduction
In this post, I will cover the things I find most important to know about writing clean code and why we should strive to achieve it.
Table Of Contents
- Why Clean Code?
- Choosing the right tools
- Keep things separated
- Code Metrics
- Things to avoid
- DRY Principle
- Implement good standards
- Self-documenting code
Clean Code
It's important to understand that besides the compiler, we as programmers should also be able to easily read our code and others as well. Badly written code can create a bad development environment for you and your team, it can increase the number of bugs in your code, decrease flexibility, and increase code complexity and redundancy, which all contribute to increased technical debt.
Why?
1. Reading code is harder than writing code!
Reading old code is hard, sometimes it might even happen that you can't read your own code you wrote 1 month ago.
2. "I will make this better later..."
If you are telling yourself that, then there's probably more than a 50% chance you won't do it ever.
3. Technical Debt
Badly written code creates technical debt, which is:
- Costly for the company;
- Cumbersome and boring for you to fix later.
4. I'm a lazy programmer
Although they say some of the best programmers are lazy, this should not apply for when you are writing your code. You can still be a lazy, good, creative, and fast programmer whilst writing clean code.
5. Clean code vs Development Speed
Some might say that the required extra care can cripple their development speed. I don't think these two things are incompatible; if you know and practice your code standards and clean code practices beforehand, when you go to code they will naturally arise without you even thinking about them.
Choosing the right tools
The first step for writing good code is having the right tools to do so. We should select the best tool for the job. This could be an IDE or programming approach to a problem. My favorite example is the validation of an email.
The email validation nightmare
The most common approach I see is the use of a regex for this task. The problem is that the regex required to do this is awful and completely fallible if done wrong.
Example of a possible email regex in C\
Example of an email regex in other languages
And depending on the language it could be totally unreadable. Check this website with the email regex for different languages. Just take a look at the Perl/Ruby implementation. 😱😱😱 What a nightmare!
An alternative for .NET developers
If you are working with ASP.NET there might be a better alternative. This to make the case of finding the right tool for the job you could use the:
System.ComponentModel.DataAnnotations
System.Net.Mail.MailAddress
All these strategies have advantages and disadvantages and we must select the one that works for our requirements and that doesn't create unnecessary complexity or a potential source of bugs.
If you want to go more in-depth about this email issue look at this StackOverflow question
Keep things separated
When dealing with a full-stack project it's a good idea to make sure that different code types are kept in different files. For instance, avoid having HTML, C#, and Javascript code in the same file (e.g., .cshtml files). Here are some reasons why:
In general separating your code will possibly allow for code highlighting and syntax verification, which makes for better readability and prematurely catches silly syntax errors. Although this might not be the case for every language and project.
When dealing with javascript, having the code in a separate file allows you to potentially cache the code and perform other optimizations like modification and compression, which might not happen if the code is on an HTML file.
Separating the code into different files will possibly promote the practice of separation of concerns and also make it reusable.
Code metrics
Nowadays we have several ways of measuring different code metrics that allow us to learn several properties about our code. Some metrics include:
- Cyclomatic complexity
- Maintainability Index
- Depth of Inheritance
- Class Coupling
- Lines of code metrics
These metrics can be automatically measured from your IDE using built-in functionality or a plugin. For instance,
- Visual Studio 2019 - Offers built-in capabilities for generating code metrics
- Resharper for VS2019 - Offers continuous code quality analysis, code smell, and error detection, and standard enforcement.
- Visual Studio Code - Offers different plugins well, check them out here
Another way of getting code metrics analysis would be static code analysis tools, e.g. the open-source tool SonarQube to perform static code analysis allowing you to detected bugs, code smells, and even security vulnerabilities. This can mainly be useful when added as a step in your CI/CD pipelines to ensure that standards and metrics are maintained.
Things to avoid when writing code
High Cyclomatic complexity
Cyclomatic complexity is a software metric used to indicate the complexity of a program.
High cyclomatic complexity is an indicator of complex and hard to follow code. It might be an indication, for instance of nested if-else statements and method calls. Try to avoid this when possible.
Zombie Code
This is code that you might find in your projects that are not being used at all or is deprecated but not properly identified as such. Over time this can amount to larger binaries, longer code to go through, and more testing required where it might not even be necessary. It can manifest in the form of unreferenced methods or functions or even blocks of commented code.
If you ever see this in your codebase, it might be a good idea to ask someone more knowledgeable about the project if it could be removed. Another strategy is to implement QA tasks in your projects to periodically tackle the technical debt of the code.
Excessive indentation and no whitespaces
The use of excessive indentation or the lack of it can create hard to follow code, sometimes the reader having to indent the code himself. Nowadays most IDEs offer some way of fixing indentation automatically and others even enforce and fix code standards. These standards can usually be customized for the developer's needs.
Long classes and methods
The rule of 7 is based on the idea that humans can only remember up to 7 things at a time. Therefore, if you create anything with more than 7 parameters it will be very difficult to manage and go through.
One thing I remember from university when studying processors is that they have something called registers and they come in a limited number. Putting it very simply and general:
For some architectures, when invoking a function, the processor uses those registers to hold those variables, because it makes the operation extremely fast. If the number of passing parameters exceeds the number of available registers then the processor needs to store the remaining parameters elsewhere, which leads to a lot more work and maybe small performance penalties.
Therefore I always try to keep the number of parameters to less than 7, usually 4 or 5.
This rule usually applies at:
- The number of parameters in a method
- The number of variables in a method
- The number of methods in a class
Unnecessary comments
All I have to say about this is, avoid doing commentaries like this:
In my opinion, we should only add comments when:
- On a property when we want to explain what it does in the given context and the name in itself is not enough.
- To explain some obscure algorithm that performs a very specific thing that isn't clear given the context where it's found.
- To justify a decision on why something was done a certain way and to avoid possible "corrections".
Poorly named data structures and variables
Poorly named variables and data structures can have a very significant negative impact on the readability of our code. In some cases, even a simple code snippet can become frustrating to decipher because of badly chosen variable names.
Another bad consequence of badly naming things is that it can misguide the reader to what the class, method, or variable are doing. This can lead to bad usage of the code and resulting in unexpected behavior.
In the second part of this post, I'll go into more detail on naming classes, variables, and much more.
Overly verbose names
That being said we should also try and avoid being too explicit on what a class or method is doing and avoid overly verbose names!
- ValidatePaymentAndSendEventMessageToPipeline()
- ValidateInputProcessDataAndReturnResult()
There's no reason why we need to be so descriptive about what's happening in those methods. Sure we can kind of guess what's happening just from the name, but we can probably also guess what's happening by looking at the code. There's no added advantage in being so descriptive. Something like this should be enough:
- ValidatePayment()
- ValidateAndProcessData()
And if it's not consider adding a //summary section above the method giving some further information about the method.
DRY principle´
The DRY principle stands for:
Don't Repeat Yourself.
As a developer this tells that we should try to:
- Decrease the amount of unnecessary code in the codebase.
- Decrease the number of lines of code and not have more of them.
"Measuring programming progress by lines of code is like measuring aircraft building progress by weight" - Bill Gates
3.Try to detect patterns that are repeating in your code and refactor them into one cohesive code block shared by the entire code base, when applicable.
Self-documenting code
In general, the code should be self-documenting, meaning that for the most part, a developer should be able to understand what it's happening in there. And to make sure that happens we should make sure we write clean code! This is not to say we should have comments describing the code, but try to be clear with your code before adding commentary on it.
Conclusion
These things I've talked about here I believe to be for the most part of general application. Do you disagree on something? Please let everyone know your experience on the matter!
So happy to being back to writing! Almost after 5 months, I started a new job in London and I am still in the process of trying to move there! Quite an adventure that unfortunately didn't leave me with much time for writing. But I'm back :D
Top comments (2)
Great article! Such a nicely written.
Waiting for the second part.
Thanks.
Thank you! I appreciate the feedback! It's coming soon :D