Clean Code

In this article we will look at more rules to make Clean Code. If you missed the first three articles that explain what Clean Code isthe general rules and the rules to names and comments, you should check them before continuing. If you have already read them, read on!

Rule nº 10: A function should do only one thing

If a function does multiple things, then you should break it into smaller functions as it is much easier to read and understand when the information is broken into small pieces.

 

				
					//For example, DON’T do this:

void makeOrder() {

   //Register the client

   //Add discount

   //Update the inventory

   //Save the order

}

//Instead of write one big functions and a comment on every functions created,
//you should have small separated functions with clear and appropriate name:

   void registerClient() { }

   void addDiscont() { }

   void updateInventory() { }

   void saveOrder() { }    
				
			

Rule nº 11: Error handling should only be about errors

If you have a function that handles errors on your application, it should only have code inside a try catch block. This reminds us of our 10th rule (a function should do only one thing), so be careful not to put code before or after your try catch block.

Rule nº 12: Don’t repeat yourself

As mentioned before, you may start writing duplicated code, and that’s ok if you are trying to make it work. But after that you should put some effort into cleaning it, moving the duplicated code into a function that can be easily accessed in both places.

Rule nº 13: Avoid passing booleans (Flags) into a function

If you are passing a boolean into a function it’s probably because you have an if statement that could be broken into two separated functions. If you just want to set a variable to true or false, then it’s ok to pass a boolean into a function. Otherwise, if this boolean is used to determine if a function should do one thing or another, then you should avoid it.

DON’T do this:

				
					void createFile(String name, bool temporary) {

   if(temporary) {

      create(‘./temporary/$name’);

   } else {

      create(‘./$name’);

    }

}

Do this instead:

void createPermanentFile(String name) {

   create(‘./$name’);

}

void createTemporaryFile(String name) {

   create(‘./temporary/$name’);

}
				
			

Rule nº 14: Don’t pass more than 3 arguments into a function

If you have a function that needs to receive more than three arguments, you should pass an object that contains all those arguments. It makes it easier to read.

DON’T do this:

				
					void signUp(String email, String password, int phone, String name, String username) { }

Do this instead:

void singUp(AccountCredentials credentials) { }

class AccountCredentials {

  final String email;

  final String password;

  final int phone;

  final String name; 

  final String username;

 AccountCredentials({

    this.email, 

    this.password, 

    this.phone, 

    this.name, 

    this.username,

  });

}
				
			

Rule nº 15: A function that has a return type should not have side effects

Void functions always have side effects; in other words, they change the state of the system and return nothing but by convention the functions that return something should never have side effects.
The main reason is that everyone should feel safe to call a return function knowing that it doesn’t change the state of the system.

Rule nº 16: Avoid negative conditionals

It’s harder to understand negative conditionals than positive ones.

 

				
					//Negative examples:

if(!cartIsFull) { }
else { }
				
			
				
					//Positive example:

if(cardIsFull) { }

else { }

//See? Isn't it much easier to understand the positive if statement?
				
			

Rule nº 17: Replace conditionals with Polymorphism

This applies to switch and if statements. With O.O.P (Object Oriented Programming) you can use polymorphism to extend a class, inheriting all its methods. This way you don’t need to use lots of conditionals everytime as they tend to be confusing and can get very messy. See the example below:

Try to NOT do this:

 

				
					class Vehicle {

   void move() {

      switch (type) {

         case “plane”:

            return fly();

         case “car”:

            return drive();

         case “boat”:

            return sail();

       }

       throw new Exception("Wrong name");

   }

}

fly() {

   print(“I can fly!”);

}

drive() {

   print(“I can drive!”);

}

sail() {

   print(“I can sail!”);

}
				
			

Instead of that, you could do this:

				
					abstract class Vehicle {

   void move() { }

}

class Plane ar implements Vehicle {

   @override

   void move() {

   print(“I can fly!”);

   }

}

class Car implements Vehicle {

   @override

   void move() {

   print(“I can drive!”);

   }

}

class Boat implements Vehicle {

   @override

   void move() {

   print(“I can sail!”);

   }

}

				
			

When you need to use the “move” method, you only need to call that method from the class you are interested in:

				
					final Boat boat;

boat.move();
				
			

This way, everytime you add a new kind of Vehicle, you don’t need to change all switch statements you have on your application (sometimes you have many of them), you only need to extend the class Vehicle. This is a principle called Open Closed Principle, which tells us that a class should be open for extension but closed for modification. 

That’s it! If you want to know more about Clean Code, don’t forget to read Uncle Bob’s book on this topic and also don’t forget to watch his series on YouTube. 

References

Martin, Robert C. Clean Code: A Handbook of Agile Software Management. Prentice Hall, 2008.

Calm Experts - Logo

Let's have a chat

Learn how we Can help from here to launch.