10 Clean Coding Practices
By: Sanura Hettiarachchi
Tags: Information Technology, Best Practices, Software Development, Coding, Software Engineering

Throughout my venture as a software engineer, I have seen people code in various ways. Sometimes it’s easier to read and understand while others took a considerable time to go through. When we code, we write it for others to read later on, not for ourselves. Even if a person is working on an individual project it’s crucial that your code is readable to another developer. I will discuss about some practices I realised that will help us code clean and better, no matter what programming language you use.

Avoid poor naming Follow correct naming conventions Create proper method signatures Keep function parameter count to a minimum Declare variables at the place of use Avoid using confusing magic numbers Minimise extensive nested conditions Don’t implement super long functions Avoid code duplication Make necessary comments

Below I will explain each point in detail with examples when needed.

1. Avoid poor naming

Short variable names

private String an;

This is a short variable name. It looks like an abbreviation. What does “an” stand for? You will have to go through the code to see the place where a value is assigned to “an” to figure out that it stands for the administrator’s name. “adminName” would have been a better option, don’t you think?

Long Variable Names

Person[] peopleFromIndiaWhoCanSpeakFrench;

This is a long variable name. You can shorten such names without losing the meaning. For example, “indiansSpeakingFrench”. Keep in mind when someone shorten the variable name, it should still be meaningful to others who read that code.

Bad Notations

int iSize;

String sName;

There are bad notations which are not applicable for modern programming concepts. For instance, Hungarian notation where a prefix letter is used to denote the data type will cause more confusion nowadays than a clarification. Integer variable “iSize” should simply be “size”.

In short, the variables should be,

· Not too short, Not too long

· Meaningful

· Reveal Intention

· Chosen from the problem domain

2. Follow correct naming conventions

There are different naming conventions in different programming languages. Few I have seen are,

· camelCase

· PascalCase

· snake_case

· kebab-case

It’s important that you follow the correct naming convention to avoid being a chaotic coder. A developer coming from a C# background would name a method in PascalCase while a Java developer would name it in camelCase. Always refer to good coding examples online if you are new to that language, also the documentations might help to find-out the best practices.

3. Create proper method signatures

Laptop getPerson(String ownerId){

//do something

}

Here you would call getPerson method with an ownerId to fetch a person, but instead it would return you a Laptop. While that function might serve its’ purpose, it’s a terrible name which should be modified to a meaningful name so anyone who’s using it won’t be misguided. “getLaptopByOwnerId” would be a more purposeful name.

void parse(int myNumber) {}

void getName() {}

Usually a method like “parse” is expected to return data after some conversion. But here the method doesn’t return anything. That would be surprising and hard to understand. Either add a return type or simply change that unsuitable method name. Same goes for the “getName” function with an empty return.

Also the signature parameters should be more meaningful instead of using an ambiguous name like “myNumber”

4. Keep method parameter count to a minimum

void myMethod(int param1, String param2, float param3, int param4, String param5) {}

The best practice is to keep your method to 3 or less parameters. While it can become hard sometimes, when you look closely there are situations where you can split the method to different functions. Also if those parameters are actually related to same entity as attributes you would be able to create a new class and pass that object to you function. This would ultimately improve reusability and readability in your code.

5. Declare variable at the place of use

void myMethod(Person person) {

String a,b,c; //after 25 lines...

a = person.getName();

}

Where should the variables be declared? Some procedural programming languages such as “C” which I learnt as an undergraduate needed to declare all the variables at the top. These types of code are hard to be read. I prefer it when variables are declared at the place where they are actually being used. That way you won’t have to scroll back and forth to understand your code.

6. Avoid using confusing magic numbers

Document getDocument(int state){

if(state == 1){

return new ActiveDocument();

} else if (state == 2){ //2 = Cancel

return new CanceledDocument();

}

}

I find it confusing to understand a code like above. state == 1? What is meant by number 1? I have seen some developers use a comment to explain what this magic number denotes.

} else if (state == 2){ //2 = Cancel

But this is not a good practice. Declare a constant to explain its’ meaning. Also you can create an enumeration if the value is being used at multiple places.

private static final int ACTIVE = 1;

private static final int CANCEL = 2;

or

public enum State { ACTIVE(1),

CANCEL(2); private int value; public int getValue() {

return value;

}

}

7. Minimise extensive nested conditions

if(a = true){

if(b = true){

state = "Active";

}

} else if(c = true){

if(b = true){

state = "Active";

}

} else {

state = "Cancel";

}

Multiple nested conditions make it hard to read your code. Always try to simplify them. Above code can be simplified as below,

If(b = true && (a = true || c = true)) {

state = "Active";

} else {

state = "Cancel";

}

Also using ternary operators is a good practice,

state = (b = true && (a = true || c = true)) ? "Active" : "Cancel";

Keep in mind not to go overboard with combining conditions or ternary operators.

Example:

If(a = true && b = true || (c = true || a = true) && d != a && c != d && (d = true || c = true) ){

}

or multiple nested ternary operators,

state = (b = true && (a = true || c = true)) ? (c = true || a = true) && d ? "Active" : "Modify" : "Cancel";

Instead of making it clear, a statement like this would make it more complicated and hard to perceive. At time it might be better to break down a condition based on context to make it more understandable.

If(isValidFreightPayment(a,b,c) && (c || d)){

} function isValidFreightPayment(boolean a, boolean b, boolean c){

return a = true && (b = true || (c = true || a = true);

}

8. Don’t implement super long methods

Try to avoid creating long functions. Just because you can read it and understand that doesn’t mean it’s a good practice. Most of the time it’s hard to understand, to change and reuse. Also it’s imported to manage cohesion in your code. (related things should be together unrelated things should not be together). A method should be short (preferably around 10 lines). It should only do one thing and serve a single purpose.

Example:

BigDecimal getAccountBalanceFromPersonId(String pid){

//fetch person from id

//get account from person account number

//get account balance

}

This function is doing multiple things, it should be broken down to serve a single purpose. Each functionality could be defined in separate methods.

9. Avoid code duplication

Another crucial factor is duplication in your code. Do you find yourself copy pasting the same code to different places with small changes (may be only variable names or some values?), stop and think about creating a common function to be called. Always stick to the DRY principle, Don’t Repeat Yourself!

10. Make necessary comments

It’s a common understanding that comments on codes are good. I don’t find this to be very useful unless in specific situations. It’s better to keep your code clean and understandable than making comments everywhere. I follow below guideline when commenting on my code:

Do not use your comments to do below,

Never state the obvious

If it’s obvious in code what you do your comment will be just a useless distraction.

//A map to store employee id and the employee object

Map<int, Employee> empIdToEmployeeMap;

Never manage version history using comments

Managing version history changes through comments is not going to be useful in the long run. This can easily be achieved through a versioning system like git.

//v1.12

function String getName(){}

Clarify through the code not comments

instead of “pf” use a more clarifying name “payfrequency”.

int pf; //payfrequency

Dead code

Never leave commented out useless code. Remove them completely. If needed use version management to restore them but don’t comment and leave out dead code.

/*function getName(){

//do something

}*/

Don’t write comments to explain the code, try to change your code to be more understandable.

Use your comments to explain whys and hows. Also you might have business reasons that might not be expressed through code that has to be mentioned as a comment.

In conclusion, I always try to follow clean coding practices when I code. Your code is your pride. I always value code reviews and feedback from the peers so I can improve myself and my coding pattern. Always remember you code for others not for yourself, that is the first step of clean coding.