
Best Practices for Writing Clean Code: A Guide for Developers
Introduction
In the world of software development, there is a seemingly endless debate about clean code practices. This article does not seek to close that discussion but to enrich it from the perspective of a developer who, after listening to various mentors, reading essential classics like Clean Code by Robert C. Martin, and facing the daily challenges of the craft, wishes to share some key points about conscious code writing. The experience of maintaining legacy code, collaborating with teams under established agreements and conventions, and continuously seeking to improve clean code practices has led me to reflect on the importance of every word in the code and its impact on future interpretation by other developers, and even oneself, during the development process or when performing maintenance or updates weeks or months after it was written.
I dedicate this article to my team Kranio, with whom we write together daily the work of our collaboration: code that reflects our individual and collective learnings, and that in the future will surely be legacy to new developers who will have to interpret our intention of functional clarity and excellence, aspects on which we focus our efforts.
If you have noticed the recurrent use of the word "work" up to this point, know that it is no coincidence. Many of us will agree that, as developers, we are the "authors" of every line and block of code written. From this perspective, we can approach code writing as what it is in a literary sense: the narration of a story, one that has a dilemma to solve, main characters, secondary characters, events, and a denouement that puts everything in its place or alternative endings if necessary.
As in any language, code is full of adjectives, nouns, and verbs; it is crucial to use them consciously so that our narration makes sense and is understood by itself, without the need for excessively elaborate documentation. If well written, the code will be clear and evident, forming paragraphs that integrate naturally into a perfectly readable composition.
Naming Variables
Giving a variable a name in the day-to-day of code writing may seem trivial, but the reality could not be further from this assumption; this task truly deserves our full attention and even reflection before naming the different characters of our narration. How can something as simple as naming our variables be so important? Yet, if we put ourselves in the place of our readers, it is crucial to have an adequate description of each element (primary or secondary character of the story told) to correctly interpret our intention.
In the following example code, there will be multiple points for reflection, but let's first try to interpret the purpose of this function after a quick read.
Although it is quite simple code, it forces us to infer its purpose guided by the function name and the processes it performs, being obscured by its enigmatic variables, among other bad practices.
Now, let's look at it again.
It is still not a particularly pleasant function, however, its intention is much clearer; it is easy to recognize the protagonist of the described process and its purpose, which despite having side effects, is evident.
Here I list some of the points I consider most relevant when naming our variables:
‍
‍Avoid misinformation
Programmers should avoid confusing or misleading variable names that hinder code comprehension. It is important to use terms that accurately reflect their purpose, avoiding ambiguous abbreviations or names that may lead to incorrect interpretations. Also, names with minimal variations can cause confusion and should be clear and distinctive. Misleading names, such as "l" and "O" which resemble "1" and "0," should be avoided to improve readability and prevent errors.
‍
Avoid acronyms, use pronounceable words
Variable names in programming should be pronounceable, as spoken language is a fundamental part of our cognitive ability and programming is a social activity. Using unpronounceable names, like "gPstbUsr," can lead to absurd situations and hinder effective communication among developers. Clear and pronounceable names allow for smoother conversations and avoid misunderstandings when explaining code to others. Regarding nomenclature, shorter is not always better; on the contrary, clearer is.
‍
Use business domain or solution domain names
To improve code clarity and understanding, it is crucial to use a consistent word for each abstract concept and avoid wordplays that may cause confusion. Function and variable names should be coherent and reflect their purpose, avoiding ambiguous terms or those without clear context. Using recognized technical names facilitates understanding by other programmers, while in the absence of technical terms, names from the problem domain should be used. Adding context to names, through classes or prefixes, also helps clarify their function in the code.
Functions
If, like me, you started your software development career in the modern times of object-oriented programming and structured programming, then the terms “routines” and “subroutines” are something we only know from “classic” literature; from there we understand that acceptable function sizes have varied from several hundred lines to the modern minimalism that seeks to simplify everyone’s life with concise and clear functions.
Functions should be brief, focused on a single task, and maintain a consistent level of abstraction. To achieve this, it is advisable that code blocks in conditional or loop structures contain only the invocation of a function with a descriptive name, thus reducing complexity and improving readability. A function that does "one thing only" breaks down a broader concept into steps of the same level of abstraction. Mixing levels of abstraction in a function or dividing it into sections indicates that it is performing more than one task, which makes it harder to understand.
In the words of Robert C. Martin: “FUNCTIONS SHOULD DO ONE THING. THEY SHOULD DO IT WELL AND IT SHOULD BE THE ONLY THING THEY DO.”
Let’s analyze again the function to get a user’s posts:
Can you notice the “side effect” of it? The function says it gets the posts of a user, but along the way it filters by a time period. According to the “single responsibility” principle, this block should be separated into its own function. Like this:
Avoid duplications
“Innovations in software development have been a continuous attempt to eliminate duplication of our source code.” Code duplication, such as repeating an algorithm in multiple places, increases code size and the risk of errors, as well as complicates future modifications. This problem can be mitigated through techniques like creating reusable methods, which improves readability and reduces risks.
Nomenclature
Consistency should be sought in verbs and nouns from modules to variables. Using synonyms to name functions in the same sequence is like changing the names of our characters halfway through a story.
Choosing descriptive and precise names for functions and methods is crucial to improve code clarity and design. A well-chosen name reflects the function’s purpose, making it easier to understand and maintain. Don’t fear long names if they are more descriptive, as they help better narrate the code’s logic. Also, using a consistent naming convention throughout the code contributes to telling a clear and consistent story. Experimenting with different names until finding the most suitable one can lead to improvements in code structure.
Functions are the verbs of the language and classes the nouns.
Parameters
The ideal number of arguments for a function is zero, and it should be avoided to exceed two, since more arguments complicate understanding, testing, and using the code. Output arguments and flags (like Booleans) are especially problematic. In functions with multiple arguments, it is often better to group them into objects to simplify. Also, using clear and consistent names for parameters is key to facilitate reading and maintaining the code. When lists of arguments are needed, they should be treated as a single argument, following the same rules.
Let’s take as an example our function to filter posts by time range. If we analyze the parameters, we see that two of them are so closely related that they actually form part of the same concept, and therefore grouping them by class would allow faster reading. Like this:
Order
We want our functions to be readable from top to bottom, like paragraphs of our narration, the content of each use is understood by the context of the previous one, and so on until reaching the conclusion.
Comments
Like many topics of discussion about clean code, comments are highly controversial. We see many articles talking about how to write “good” or “meaningful” comments, however, I believe we can all agree that the best comment is the one that was not necessary to write.
Recapping on the concept of the narration that the code tells, we can reconsider that good code explains itself. In the same sense, whenever we feel the need to write a comment, first analyze if what we should really do is refactor the code in a way that this comment is not necessary due to the clarity of the code per se; this prioritization will always yield better results.
Utility
Well-placed comments can be useful, but dogmatic and outdated comments can be harmful. While in an ideal world, programming languages would be so expressive that we wouldn’t need comments, the reality is that comments are often used to compensate for our inability to fully express ourselves through code. Despite this, comments should not be celebrated as an ideal solution, but seen as a necessary evil.
Tendency to misinform
Comments can be misleading and outdated. As code changes and evolves, comments tend to lag behind and can become incorrect. A common example is a comment that no longer matches the code it refers to, especially when new variables or other changes are added. Imprecise comments can cause confusion and create wrong expectations, so it is better to minimize their use and focus on writing clear and expressive code.
Comments versus clear code
A frequent reason to create comments is to explain disorganized or incorrect code. However, it is more effective to fix the problem rather than rely on comments to clarify confusing code. Clear and well-structured code is preferable to complex code full of explanatory comments.
Well, this brings us to the end of this reflection; there are still many topics to address regarding important practices to consider when writing clean code. Until next edition!
Ready to improve the quality of your code and adopt more efficient development practices?
At Kranio, we have software development experts who will help you implement clean code practices, improving the readability, maintainability, and efficiency of your projects. Contact us and discover how we can boost the quality of your code and the productivity of your development team.​
Previous Posts

Google Apps Scripts: Automation and Efficiency within the Google Ecosystem
Automate tasks, connect Google Workspace, and enhance internal processes with Google Apps Script. An efficient solution for teams and businesses.

Augmented Coding vs. Vibe Coding
AI generates functional code but does not guarantee security. Learn to use it wisely to build robust, scalable, and risk-free software.
