Basic principles based on the book – Clean Code Robert – C. Martin
Some time ago I read the book „Clean Code“ by Robert C. Martin. I approached it with curiosity, but I have to admit, as it’s usually the case with technical books, that it was not a piece of cake. A lot of code to analyze slows down reading a bit, and focusing on Java also means that not all aspects of the book are universal.
So I thought that I could summarize the most important aspects common to different programming languages and create a small introduction to clean code.
I think it will be a good introduction for junior programmers and some revision for a bit more advanced ones.
What is Clean Code? In my opinion, clean code is like a good book, everyone who reads it will know what is going on.
The problem with bad code is that we often don’t focus on code quality because time is running out. Because we’ll fix it later. Because we need to add something to the current code and we don’t want to mess with it too much, so we’re adding more bad code.
This is where further problems arise. Bugs that are hard to identify, code that takes a long time to understand, etc.
Unfortunately, sometimes (often) even the author can’t decrypt their own bad code after some time:-)
Therefore, in the following points, I will try to explain a bit the basic concepts of the book. Of course, I also encourage you to read the book.
Names should reflect intentions and be descriptive
A wrong name for a function, variable, or even class is often a problem. The name of the function should indicate what it is for and what to expect after its execution. Variable names should indicate what information they hold.
Create clear differences
Avoid giving similar names to functions / methods / classes.
What function should we use? How do they differ?
- moneyAmount = money ??
- accountData = account ??
Names that can be pronounced
It’s just easier to work with names that are easy to pronounce and remember. When talking about code, it will be easier if you can pronounce the name of a variable / function.
The discussion about the first code will be more problematic than about the second one below.
Names of classes and functions
Class names should be nouns or noun phrases e.g.:
Function names should be verbs or verbal expressions:
One word per concept
One specific word for one abstract concept should be used.
It can be confusing to use the names fetch, retrieve, get for similar methods in different classes.
They should be as short as possible
It has been assumed that the maximum size of the function should not exceed 20 lines of code.
One function should contain a maximum of 2 indents, if / else / while blocks and similar are considered as indents. They should be single-line, so they should contain a function call.
They should do only one thing
Reading the code from top to bottom – „Top down rule“
For convenience, we want to read the code from top to bottom. That’s why after each function there should be another one at the next level of abstraction.
Avoiding side effects
This is, of course, related to naming functions. Let’s take such a function as an example:
We expect the above function will check the password, but a session initialization is an unexpected side effect here.
Therefore, to avoid a side effect, the name of the function should be changed to e.g. checkPasswordAndInitializeSession.
Ideally, functions should take up to 2 arguments, maximum 3. When more is needed, they should be passed as an object. The boolean argument should also be avoided, as it indicates that the function is likely to do more than one thing.
Using exceptions instead of error codes
It is probably rare, but it sometimes happens: error codes are returned from functions. This should be avoided and exceptions should be thrown. Problem with error code is that it must be handled immediately.
With try-catch blocks, error processing can be separated from the correct code execution path.
Also note that functions that contain a try-catch block should do nothing but handle errors.
Often code could function without any comment, but sometimes developers prefer to add an explanation comment rather than „code“ it, e.g.:
There are, of course, „good“ comments, including:
- Legal Comments
- Informative comments
- Comments of intentions
- TODO Comments
- Consequence Warnings
- Javadoc /… doc comments in public API
I don’t want to focus on describing them, I encourage you to read the book.
The basic rule in writing tests is that tests should be written along with the code. As the code changes, the tests should also be updated.
Here are some additional rules:
One assertion per test
Sometimes it seems obvious to make more than one assertion in a test. However, there is a programming school that says that there should be one assertion per test.1
This has some advantages, because in the case of a failed test, it is easier to find the error. For example, a fairly simple test:
A fairly simple test can be made into 3 smaller ones, which may seem redundant, but with more tests and appropriate names it is easier to spot possible problems.
One concept per test
It is important give each test function a single concept . We shouldn’t write long test functions which test one thing after another. It is also related to the principle described in the previous point: after separating tests they are both clearer and easier to understand.
Clean tests shall follow five F.I.R.S.T rulet:
- Fast – tests should work fast
- Independent – tests should not depend on each other. They should work individually and in a chosen order.
- Repeatable – tests should be repeatable in every environment: developer, production, on a laptop…
- Self-validating – should give clear information: success / fail
- Timely – tests should be timely written , i.e. immediately before the tested production code is created.
In my opinion, these are the most important basic rules of writing good, readable, clean code. There are of course more detailed rules and recommendations, if you would like to know more you’d better read the book.Interesting? Share the article with your friends!