Writing Clean and Maintainable Code: Short Tips about Naming and Functions

Ehsan Movaffagh
5 min readMay 14, 2024

Introduction

Why clean code is important?

To start, It’s crucial to know why clean code is important. I’ll give you some examples to show you why it is important.

Assume that you joined a company and you want to clone their source code. after cloning you want to understand how they implement their business logic. Their functions are long and their naming could be better!! that’s a terrible thing and you wish they wrote better code than you know to understand things in your code. I will tell you some of the work we can do about making names or things about functions to have a cleaner code.

I need to say that the reference of this article is the Clean Code book written by Uncle Bob.

Naming things

Proper naming of variables, functions, classes, and other elements in code can save us a lot of time in understanding the business logic behind it.

In this section, I’ll give you some advice on the dos and don’ts of naming the elements in your code.

Use Intention-Revealing Names

Clear and concise naming provides us with information about each element's purpose and functionality, helping us understand why it exists and how it contributes to the overall code structure.

For example, consider this:

let d; // elapsed time in days
let m; // elapsed time in months

I prefer to remove the comment and add it to the variable name somehow:

let elapsedTimeInDays;
let elapsedTimeInMonths;

that’s better for the future developers (and of course you in the future) to understand what is happening here.

Make Meaningful Distinctions

Imagine a scenario in which you have a real-time event and you want to show a user list to users. you wrote this simple function that creates a list of the users who have logged in to the specific event. The first argument is the event holders and the second argument is the users who are watching the event.

function makeUsers(users1, users2) {
return [...users1, ...users2]
}

You didn’t remember what users1 are and why they are on the first of the list. Are they more important than users2? and what is makeUsers? What it will do?

I know you can write some comments about them but if you change something about these stuff, would you update the comments too? I don’t think so :))

The better naming is something like this:

function getAllEventUsers(eventHolders, participants) {
return [...eventHolders, ...participants]
}

Avoid Disinformation

What’s disinformation? To avoid it, we should know exactly what it is. In this case, it means leaving false clues in the names of things in the code, making it unclear. For example, if you have a list of users don’t name it userList name it users if the data structure of that variable is not a list it could cause a false conclusion!

Another disinformation is if you have long-named variables which are hard to recognize! For example, consider this:

let baseControllerForHandlingLogin;
let baseControllerForHandlingLogout;

They’re alike and it’s tough to tell them apart. Avoid using names that make it hard. You want to quickly get the differences without thinking too hard!

Class, Object, and Method names

Classes and objects represent entities or concepts, so it’s more appropriate to use nouns for their names. For example, Customer, Car, Account, etc.

Methods typically perform actions, so you should use verbs in their names to indicate what action they perform. For example, calculateTotal, postPayment, displayMessage.

I believe with these simple hints about naming, your overall code naming would be much better and more understandable.

Functions

In this section, I will provide some hints about functions and how they should be. In JS, we typically use functions; In our components, API handlers, etc.

Should be Small

I don’t know if you’ve seen Fight Club or not, but, There are some rules about functions to be clean too.

First Rule: Functions in your code, should be small.
Second Rule: Functions in your code, should be small.

this is very important for our functions to be small. If they aren’t small, we would be confused about what exactly they’re doing And we will lost in that long function.

They Should Do One Thing

We should separate the responsibilities of our single function into multiple functions to do exactly one thing. and they should do that one thing pretty well.

For example, see this function:

async function renderProducts() {
const products = await fetch('/products')

const productList = document.createElement('ul');
products.forEach(product => {
const listItem = document.createElement('li');
listItem.textContent = `${product.name}: $${product.price}`;
productList.appendChild(listItem);
});
document.body.appendChild(productList);
}

renderProducts()

First of all this function fetches products and then renders them on our page. As you can see this function is doing two different things. So we should separate them:

function renderProducts(products) {  
const productList = document.createElement('ul');
products.forEach(product => {
const listItem = document.createElement('li');
listItem.textContent = `${product.name}: $${product.price}`;
productList.appendChild(listItem);
});
document.body.appendChild(productList);
}

// we can use fetchProducts in other places too!
async function fetchProducts() {
return await fetch('/products')
}


fetchProducts().then((products) => {
renderProducts(products)
})

These two fragments of codes do the same thing but in multiple functions!
The second one is much better because it separates the responsibility of our single function to do multiple functions and they do their jobs exactly as we wanted to.

Arguments

One of the most important things in functions is their arguments and in other words, their inputs.

It is way better to have a small number of arguments. If we had a lot of them something goes wrong and we should rethink the structure of that function. For example, the arguments could be in a data structure or class for us to be more convenient.

See this example:

function sendShipmentNotification(shipmentId, userEmail, message, items) {
let notificationMessage = message;
notificationMessage += `\n shipment: ${shipmentId} \n`;
if (items.length > 0) {
notificationMessage += "\n\nItems in the shipment:\n";
items.forEach((item, index) => {
notificationMessage += `${index + 1}. ${item.name} - ${item.quantity}\n`;
});
}

pushNotification(userEmail, notificationMessage)
}

this function should improve in many ways and aspects but my focus is on its arguments:

class ShipmentMessage {

constructor(items, shipmentId, message) {
this.items = items
this.shipmentId = shipmentId
this.message = message
}

get notificationMessage() {
let notificationMessage = this.message;
notificationMessage += `\n shipment: ${this.shipmentId} \n`;
if (this.items.length > 0) {
notificationMessage += "\n\nItems in the shipment:\n";
this.items.forEach((item, index) => {
notificationMessage += `${index + 1}. ${item.name} - ${item.quantity}\n`;
});
}
return notificationMessage
}

}


function sendShipmentNotification(userEmail, shipmentMessage) {
pushNotification(userEmail, shipmentMessage)
}

As you can see we separate the concerns of that function and also create a class with a getter notificationMessage to avoid so many arguments in our main function.

I think this is Enough for functions too!

Conclusion

And here we are! We discussed about naming and some function rules to write more clean code 👨‍💻 👩‍💻.
With these simple hints, our code could be much better than it could ever be.

I hope you enjoyed it!

--

--

Ehsan Movaffagh
Ehsan Movaffagh

Written by Ehsan Movaffagh

Full-stack engineer, crafting innovative solutions to shape the digital world🚀; https://linkedin.com/in/ehsan-movaffagh

No responses yet