Partager

30 décembre 2020

My point of view on clean code

Matthieu Hahn, Senior Software Devellopeur chez Kumojin nous apporte sa vision, son expérience et son approche du Clean code!


I recently encountered a PHP project that made me want to write about clean code.
SitRep: One of our clients has a website that needs some bug fixing and some features to be added. Once I had cloned the GitHub repo, I took a look at how the code was written and my reaction was:

holy

Ok, slight exaggeration here 😅, but you get me.

So here are my thoughts about how useful it is to write clean code

What is clean code anyway ?

I guess thousands of lines could be written about this topic, but in a nutshell, I'd say clean code is code that is going to be easy to maintain. Easy to maintain not only by yourself in one week, but probably other people months later when you're no longer here to explain it.

Ok now let's get on with it then.

Readability

To me, this is probably the most important in writing clean code.
The code you write MUST be readable by another human being without generating this kind of reaction:

crap

Naming variables and functions

a, b, c, test, thing, ... are not good variable names, that's pretty obvious, but I still occasionally see them around 😅. I recently started to look into Golang and it seems quite frequent to see badly named variables there 🤔.

// Don't
function calcTwt(a, b, c) {
  return a * b * c;
}

// Do
function caculateTotalWithTaxes(quantity, unitPrice, taxes) {
  return quantity * unitPrice * taxes;
}

Of course, no need to overdo it, keep names short but understandable.

Also, there are many standards about naming variables already out there. For example, boolean will often be written isOpened, areOpened, hasRead.

Here's a pretty good article about naming stuff: https://hackernoon.com/the-art-of-naming-variables-52f44de00aad

Keep your functions simple

Your functions should only do what they say they do. For example, if you call your function getUser and pass an id param to it which would be getUser(id), it should only fetch and return the user which has this id, and that's ALL.

Also, if your function is too long and does many different actions, it's probably a sign that you should split it into multiple smaller functions.

Formatting

Here are a few tips about formatting your code:

  1. Keep your files from being too long
  2. Limit the length of lines
  3. Last but not least, comply by the rules set by your team

Coding principles

DRY

Don't Repeat Yourself.

That's pretty straight forward ain't it. It states that every piece of code you write should only have one clear representation in your project's codebase.
In other words, you shouldn't write the same piece of code twice. If you are, then your code is going to be more difficult to maintain.

Here's a simple example, you have a list of users and want to display the concatenation of the firstName and lastName.

const users = [
  {
    id: 1,
    firstName: 'Luke',
    lastName: 'Cage',
  },
  {
    id: 2,
    firstName: 'Jessica',
    lastName: 'Jones'
  }, 
  {
    id: 3,
    firstName: 'The incredible',
    lastName: 'Hulk',
  }
]

// Don't

console.log(`${users[0].firstName} ${users[0].lastName}`);
console.log(`${users[1].firstName} ${users[1].lastName}`);
console.log(`${users[2].firstName} ${users[2].lastName}`);

// Do
function displayUserName(user) {
  console.log(`${user.firstName} ${user.lastName}`);
}

users.forEach(displayUserName);

KISS

Keep It Simple Stupid is a design principle noted by the U.S. Navy in 1960 meaning you should avoid unnecessary complexity as much as possible. If things are kept simple, they are easier to understand and therefore easier to maintain.

https://en.wikipedia.org/wiki/KISS_principle
kiss

Here's a silly example, but it should make it clear to you.

// Don't
function dayOfWeek(dayNumber) {
  switch(dayNumber) {
    case 1:
      return 'Monday';
      break;
    case 2:
      return 'Thuesday';
      break;
    case 3:
      return 'Wednesday';
      break;
    case 4:
      return 'Thursday';
      break;
    case 5:
      return 'Friday';
      break;
    case 6:
      return 'Saturday';
      break;
    case 7:
      return 'Sunday';
      break;
    default: 
      return null;
  }
}

// Do
function dayOfWeek(dayNumber) {
  if (dayNumber < 1 || dayNumber > 7) return null;

  const weekdays = [
   'monday',
   'thuesday',
   'wednesday',
   'thursday',
   'friday',
   'saturday',
   'sunday',
  ];

  return weekdays[dayNumber - 1];
}

YAGNI

You Aren't Gonna Need It.

One thing I learnt in my beginner years was not to write functions before you need them. Otherwise, you're probably going to create dead code.

For example if you're writing a user class, don't assume you might later need a method to concatenate the first name and the last name, only write it when you need it.

One way of achieving this principle is to write the code as you're going.

Imagine you want to display a list of users in an MVC language like angular, then you should theoretically write things in this order:

  1. The view --> needs a users variable from the controller
  2. The controller --> needs a getUsers function from the service
  3. The service --> needs a fetch function from the httpService
  4. HttpService --> And so on ...

Writing your code in this order should prevent you from creating functions you won't be using.

Please keep in mind that this is my way of avoiding to write dead code, you could also go "bottom up", start with the services and end up with the view.

Conclusion

I voluntarily kept this pretty short, I could, of course, go into details for all of those topics but the idea was to give a hint to beginners on how to keep their code clean.
You should always bear in mind that all teams have their standards of writing code.

Kumojin Tech