5 Clean Code Habits for Writing Better Functions
In this blog post I'll go through five functional patterns help you write code that doesn't make your coworkers want to pull their hair out.
1. Verbs over Nouns
Have you ever opened a file and seen a function simply named Product()? As a reader, I have no idea what this does. Is it creating a product in the database? Is it fetching it? Updating it? Functions do things. So, their names should always start with a verb. fetchProduct() or createProduct().
2. The Parameter Position Trap
We’ve all written a function signature that looks like this: createProduct(title, description, price, quantity, category, image), When you have more than three parameters, you are playing a dangerous game with the person calling the function. They have to remember the exact order. If someone accidentally swaps the category and image arguments, the compiler might not catch it, and your database will silently save corrupted data.
A solutions to this can be - limit parameters to 2 or 3. If you need more, wrap them in an object.
createProduct({ title, description, price, quantity, category, image });
3. Fail Fast, Return Early
When writing validation logic, our default instinct is to nest if-else blocks.
if (user.age >= 18) {
if (!userExists) {
}
}
becomes incredibly hard to figure out which closing bracket } belongs to which condition. To fix this we can just Invert our conditions and return as early as possible.
if (user.age < 18) return;
if (userExists) return;
4. Kill the Raw Boolean Flags
Imagine reviewing a pull request and seeing this line of code: registerUser(userData, true) What does true mean here? You have to stop reading, go find the registerUser function definition, read it, and come back. It completely breaks your reading flow.
const SHOULD_RETURN_TOKEN = true;
registerUser(userData, SHOULD_RETURN_TOKEN);
With that one small change, the code documents itself.
5. Keep a Single Level of Abstraction
This is a classic issue in Express.js or Next.js controllers. You open an API route, and inside one massive function, the code parses the HTTP request, validates the email, hashes the password, writes to the SQL database, and sends an HTTP 200 response.
A function should only do one thing. Don't mix high-level logic (HTTP responses) with low-level logic (database queries).
Extract validation into a
validateUser()function.Extract database logic into a
UserService.createUser()function.
Your main controller shouldn't do the heavy lifting; it should just act like a traffic cop orchestrating these smaller, predictable functions.