Clean code by Robert Cecil Martin: My takeaways
Published: 2022-09-20 06:52:21

Another great book I've had the time to go through. The insights and advice given by [Robert Cecil Martin](https://en.wikipedia.org/wiki/Robert_C._Martin) are the result of years of experience in the field.

So as usual, I'll summarize my **takeaways**, those that as a developer I want to keep in mind.

## What is clean code?
So far, the best definition of clean code I've read in the book comes from Michael Feathers.

> Clean code always looks like it was written by someone who cares

And I couldn't agree more. When code is written by someone who **cares** it's easy to read, pleasant and will tell you **precisely** what you need to know about it.

## The boy scout rule
> Leave the campground cleaner than you found it.

It happens to all of us. You have to develop a new feature in an existing code base, or fixing a bug. If you are going to touch a part of the code base, why not leave it **better** than it was before?

But wait, I might hear you saying "But what If I break something?". That's what unit **tests** are for ;)

## Naming
The book also focuses a lot on **naming** things properly. Functions, variables, classes. They all should have intention-revealing names.

Classes should have nouns or noun phrases.
Methods should have verbs or verb phrases.

And the length of a name should be related to the size of its **scope**. The broader the scope is, the larger the name should be.

## The paperback model
The author is responsible for making himself **clear**, and not the academic model where the scholar has to dig the meaning.

The code should be **self-explanatory**, and clear to the reader. The developer who is going through the codebase shouldn't have to have a hard time trying to understand what the previous developer meant. 

The responsibility and the effort are on the developer who is writing the code to make it easy to understand. And not with comments, with **code**! 

## Overloaded constructors
When constructors are overloaded, use state factory methods that describe the arguments instead.

An example given in the books is:

> Complex fulcrumPoint = Complex.FromRealNumber(23.0):
is generally better than
Complex fulcrumPoint = new Complex(23.0);

## The rules of functions

> The first rule of functions is that they should be small. The second rule of functions is that they should be smaller than that.

## Code in conditionals and whiles
The blocks within if statements, else statements and while statements should be one line long. 
If it can't fit in that, use a **function**.

## Flag arguments
If you have to pass a boolean flag to a function to determine its behavior, that function is doing more than one thing and **violating** the SRP principle. 

That function should be **split**.

## Function with too many arguments
When a function needs more than two or three arguments, some of those arguments can likely be wrapped into a separate **class**.

## Functions responsibility
A function should either do something or answer something. **Not** both.

## Comments 
Comments are, best case scenario, a **necessary evil**. Comments are there to compensate for our failure to express ourselves in code. 

So if you have to comment something out, you haven't done a good job expressing in code what you intended to do.

## Dependent functions
Whenever a function calls another function, it should be vertically close in the code, and the caller always be above.  

## Nulls
> Returning null from methods is bad, but passing null into methods is worse.
Except for API that might force you to do that.

So **don't** return nulls.

## TDD Laws
**First Law:** You may not write production code until you have a written failing unit test.
**Second Law:** You may not write more of a unit test than is sufficient to fail, and not compiling is failing.
**Third Law:** You may not write more production code than is sufficient to pass the currently failing test.

If you want to see also Robert in action explaining TDD you can check one of his talks [here](https://youtu.be/58jGpV2Cg50?t=1305).

## F.I.R.S.T
Clean test should follow five rules:

**Fast:** They should be fast and run quickly.
**Independent:** They should not depend on each other.
**Repeatable:** They should be able to run in any environment.
**Self-validating:** They should have a boolean output.
**Timely:** They should be written in a timely fashion. So, the test is written before the production code, not after.

## Classes
Classes should have a small number of instance variables. Keep the **cohesion** low.

If a few functions share the same variables, split them into a separate class.

## SOLID principles
**The single-responsibility principle:** There should never be more than one reason for a class to change. 
**The open-closed principle:** Software entities should be open for extension, but closed for modification.
**The Liskov substitution principle:** Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it. 
**The interface segregation principle:** Clients should not be forced to depend upon interfaces that they do not use.
**The dependency inversion principle:** Depend upon abstractions, not concretions.

You can find more information [here](https://www.baeldung.com/solid-principles).

## The principle of least surprise

If you do something in a certain way, do all similar things in the same way. Keep the consistency.