Wash your hands, brush your teeth, clean your code

A Clean Code rant

Clean code

The first time I saw the drawing below I laughed so loud that it might have been the only time the term lol was actually used properly.

Clean code: WTFs per minute

Still, jokes aside, having a code base is the reason we have bugs in the first place. Imagine having a messy one, right?

Hey! Bugs can be found even without a code base! Check the reported issues on this repo🙈

Alright! Let’s get serious!

Why clean code matters?

Coming from a background with PHP and JS, I’ve seen so much spaghetti code that the Italian in me now prefers burgers! The sad thing is that most of that spaghetti code was my own fault!

Clean code matters when:

  • you spend hours of work to fix an error fixable in less than ten minutes;
  • you’re reading a code and wonder whether that’s the end of the ‘if’ statement or the ‘closure’ you’re in;
  • you’re putting debug points after every ‘{‘ to see when it gets executed;
  • you search across all the project to find the one reference to that variable;
  • you search a function definition and you find several functions with the same name, in different classes, with no documentation, you know documentation matters!

Write clean code, ’cause it matters!

How to Write Clean Code?

There are few steps to take that will immediately yield some results, such as:

  1. Write some code.
  2. Test it.
  3. Go back to that code and look at it, does it look nice? No? Start cleaning it!
  4. Repeat steps 2 and 3 until the code looks nice, is readable, and clean!
  5. Don’t use shortcuts, hacks.
  6. Don’t use advanced Sci-Fi operators that others can’t understand. If you do, put a comment with a link to where people can find you, so they can ask you about that, or blame you, or publicly shame you.

That being said, here are some of the best practices for clean code. Some of them are universal, some of them are language specific. Let’s have a look.

The right way

There are some principles to follow when we want to write a good clean code.

1. Understand your code

Sometimes, we have a rush of copy-paste from our favorite site stackoverflow.com, which only in rare cases works right out of the box. So, if it does, then let’s leave it there! Right?

Wrong! Read that code, and make sure you understand it! If you don’t, try it harder or ask someone. It’s fundamental for you to understand it! Once you do, you’ll see how to improve it, remove duplicates, make it your own.

This helps a great deal and is a key point in having a clean code as well as learning new skills.

2. Use the DRY principle

DRY is an acronym for Don’t Repeat Yourself, and it’s a principle that aims to avoid repetition in your code. Let’s take a practical example:

Let’s suppose that we have a product with the base price of 100 and we want to discount it and display all the amounts with a precision of two decimals. The code is the following …

var mainPriceText = '$' + parseFloat(price).toFixed(2);
var discountedPriceText = '$' + parseFloat(price / 1.05).toFixed(2);
var discountAmountText = '$' + parseFloat(price - (price / 1.05)).toFixed(2);

This would work, right? Yes, it would, but let’s assume tomorrow we have to change the formatting of the price, in how many places would we need to change it? The answer is in too many.

Using the DRY principle we can write the code the following way:

function getFormattedPrice (price) {
    return '$' + parseFloat(price).toFixed(2);
}

var basePrice = 100;
var discountedPrice = basePrice / 1.05;
var discountedAmount = basePrice - discountedPrice;

var mainPrice = getFormattedPrice(basePrice);
var discountedPrice = getFormattedPrice(discountedPrice);
var discountAmount = getFormattedPrice(discountedAmount);

This is a far cleaner code and we can be sure that changing the price format won’t break anything.

3. Small functions and YAGNI

We all have seen and written functions that handle too much logic in one place. It’s probably a supermassive black hole of code that will eventually get hard to extend, debug, or understand in the long term.

The thing is that all of these massive functions, can and should be broken into smaller ones. Each of them should do a separate part of the job, that can and should be reused elsewhere. There’s a limit to how small a function should be. If the code is very specific and won’t be reused anywhere else, then it’s fine to sit in the function itself, but make sure it’s documented well and readable (understandable) well by others. After all, the main purpose of a function is to be re-used to avoid duplicate code, we should not add functions for the sake of “It’s more readable this way.” Even if it is, it will increase the overall complexity of the system, and therefore make it less maintainable.

There’s a principle about this too, it’s the YAGNI or “You Ain’t Gonna Need It!” which in few words means don’t do it unless you need it.
This means that before writing any new functionality, feature, function, class we should ask ourselves “Is reusable?”, “How much sense does it make?”, “Can I call this function from another place?”.

4. Law of Demeter (OOP)

This is one of my favorite principles and it’s the principle of least knowledge.
The law states that a method M of an object O may only invoke the methods of the follwing kinds of objects:

  1. O itself, the object that has the M method;
  2. M’s parameters, in case those are objects with methods, it’s perfectly fine to use them;
  3. Any object created or instantiated with M;
  4. O’s direct components objects, like attributes of O that are objects;
  5. A variable, accessible by O that’s in the scope of M.

5. Naming conventions

Every language has its own naming conventions, and we’re going to talk JS and PHP here.
Usually, I prefer using the camelCase convention for functions, while underscores ‘_’ for variable names in PHP and camelCase variables in JS.
Classes should always start with a capitalized letter, no matter the language.

Names should be meaningful: don’t just use var x, y, z;, instead use var divHeight, divWidth, divOffset;. This way the person reading your code will not curse you for a wasted time since they’ll be able to debug faster. But we can go a step further and name them var headerDivHight, headerDivWidth, headerDivOffset; so how much is enough? Hard to say because longer names are harder to read, so we need them short but descriptive, something like var headerHeight, headerWidth, headerOffset;, please avoid var divTopHeaderMobileHeight.

6. Indentations (Tabs vs Spaces)

A rightly indented code, other than being easy to read and good looking, helps debug astoundingly faster than a messy one. You see, all of the points above can be disregarded if the code you wrote is a total mess with indentations. Nobody would be able to read it and understand it, that’s why I have the urge to format every code I work on! When you get the hands on a codebase that you will have to work on, follow the Boy Scout Rule, that states “Leave the campground cleaner than you’ve found it.”.

Conclusions

The main audience of your code is a colleague of yours somewhere in the world, and you can make us all a big favor by keeping it as clean as you can. Make sure to remember the Boy Scout Rule and practice the principle above.

Last but not least check our blog and find other interesting articles about engineering, remote work, company culture, and more.

Aleksandar Pavlov
Team Lead and Senior Software Engineer