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.
- Why Clean Code?
- Choosing the right tools
- Keep things separated
- Code Metrics
- Things to avoid
- DRY Principle
- Implement good standards
- Self-documenting 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.
Reading old code is hard, sometimes it might even happen that you can't read your own code you wrote 1 month ago.
If you are telling yourself that, then there's probably more than a 50% chance you won't do it ever.
Badly written code creates technical debt, which is:
- Costly for the company;
- Cumbersome and boring for you to fix later.
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.
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.
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 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.
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!
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:
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
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.
Separating the code into different files will possibly promote the practice of separation of concerns and also make it reusable.
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.
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.
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.
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.
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
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 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.
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!
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:
And if it's not consider adding a //summary section above the method giving some further information about the method.
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.
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.
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