Why GoodNames Matter? #CleanCodeP2

Why GoodNames Matter? #CleanCodeP2

Part2 of Clean Code series, we'll talk about Naming Conventions and more

Welcome back guys🤓, I'm continuing the #CleanCode series and this is part 2.

In today's blog:

Naming the things means how we call our variables, functions, and class-constructor methods to make them relevant to their applicable terms.

In a previous blog📑, we discussed the significant pain points where we generally forget to follow naming conventions. In this blog📑, we will dive deeper into just Naming. we talk about all those namable things in development (and in coding tech in general), which would be variables, constants (and properties), functions and methods, and classes.

Why do Names Matter?

Generally, we name anything just to get familiar with that thing and giving it a noun makes it more connected🤝🏽 to us. However, we do give names based on their properties🎀, appearance🎭, location, existence etc. Hence those names contain some meaning and uniqueness. Good and meaningful names help us to remember the thing and its functionality. We can easily call those names whenever we need to. Ambiguous😌 and one-letter names tend to increase complexity🥺 in learning and understanding the variable's existence, hence we can't call in the meantime when we required it. Through proper names, we make code maintainable and affordable.

So naming matters because we rely on those names in the future🤔. We can't just name our variables or data set any name which we can't even use or find🧐 when we need it. The names should transport🏇🏽 their meaning and existence without going through the whole code for their functionality and details.

const pro = new Entity();
pro.save();

if(auth) {
// do something..
}

In the above code snippet, what does 'pro' stands for?🤔 What this snippet is all about? Without proper names, we can't guess the functionality of the variables. This problem exists not just in the coding field but in every field.

In a PowerPoint presentation💻, if the presenter does not give a proper name🤮 to its entities and variables, s/he can't convey👦🏽 its properties to the audience. S/he can't even present the variables in the right way that they should be presented.

In Database Management, be it sequential or non-sequential, we name our schemas, tables📋, and their different variables to fetch them when we require them. If we name them without considering their meaning, we can't recall them in the time of fetching.

// code should be like this..
const newProduct = new Product();
newProduct.save();

if(isAuth) {
// ie, if the user is authenticated then user get access to something inside this condition.
}

What name should convey?

When we code, as we talk about in the previous blog, it should be like you're telling a story🤴🏽👸🏽. So in a story, we have a plot🗺, characters🤴🏽👸🏽 and situations💃🥱. The characters are named on their characteristic features. Similarly, variables, functions, methods, and classes are our characters. We should name them on the basis of their characteristics. For e.g,

// if we are creating a user model,
class User {
// not class Us or Data etc.
constructor(params we get) {
    // initialising ...    
    }
// methods associated with the User model
findById()
isUserExists()
signup()
// etc..
}
// similarly 
if(isAuth) {...}
//or
const existingUser = await this.isUserExists();
//or
const hashedPassword = await bcrypt.hash(this.password, 12);
// or
const orders = await db
            .getDb()
            .collection("orders")
            .find()
            .sort({ _id: -1 }) // descending order, latest on top
            .toArray();
// all these one line code snippet tells its own story, without its preface.
// Good Comments is also included in CleanCode practices.. (We'll talk about GoodComments in another blog.)

Similarly in MySQL, MongoDB or in other DBMS, we initialise the schemas and tables with different columns. All need proper names with proper identities so that they can justify their existence👌. Well-named variables allow readers to grasp the content easily.

Hence good names and if we emphasised that, relevant name do matter in code and in all other relevant fields where we do give a name to variables or data containers.🛒

However, we can't always give proper names to all the variables, sometimes we do have to adopt shorthand but that term also should be relevant to that variable.

How do we name things correctly?🎡

First of all, we should consider the naming conventions which we have to follow for certain programming languages🈹🈚. Naming Conventions are considered the pseudo syntax of those programming languages. In this, Name Casing is considered for naming the variables according to the prescribed way. There are four types of name casing prescribed for coding and naming variables:

Name CasingExamplesused in
snake_caseis_validPython, DBMS
camelCasenewUserJavaScript(JS)
PascalCaseFormerClass (for class names)Python, Java, JS
kebab-case<side-drawer>(custom HTML element)HTML

How do we name our "Things"?💌

Secondly, we have to know about the term/variable of which we are conferring the name. If we take a coding perspective, here we give names to three(3) important terms/things, these are:

  1. Variables and constants

  2. Functions and Methods

  3. Classes

So we take them one by one.

Variables/Constants: ♻

These are data containers that either stores the data or transport the data. Here we use them as input data, for validation or as a list of items. Their names should be concise and descriptive. We should use nouns or short phrases with adjectives while naming these data containers.

For eg,

var num;
let number;
const array = [1,2,3,4];
const numObject = {1: a, 2:b};  // or numObj
const userData = {...};
let boo = true;  // or boolean
let isActive = true;
let isLoggedIn = false;
let isValid = false;
What do we store?Good NamesBad Names
A user Object(name,email,age)userData, userEmail, email, ageus, data, container
user input validations(boolean)isUser, isLoggedIn, isAuth, isValiduser, login
product descriptionitemNum, itemId, id, addressprod, i , add,

Functions/Methods:☦

These are commands or operations to execute. Whether we execute it for any value or for a boolean, we should consider its possible outcomes and objective while naming these commands ops. So we should use verbs or short verbal phrases to name them. However, we also have to stick with built-in methods of the particular library or language, like now(), strftime() etc.

For Eg.,

What do we perform?an operationcompute boolean
user datagetUser(), sendData(),save()isValid()
user emailSignup(), login()isEmailValid()
save user, productsave() , user.store()isPreasent(), isAlreadyExists()
find UserallUser(), getUserByEmail()isUserExist()
// simialrly
inputIsValid()
getUser()
findAllUsers()
findById()
getDatabase() // or getDb()
updateUserData()  // etc
// all these functions/methods are self explanatory

Classes:🆑

These are blueprints of a general model of our variable object which we construct while declaring our local variable. Hence these are also nouns. We use classes to create things like products, users, request-body etc.

For eg; User{} , Product {} , RequestBody{} etc ;

object model of?describe the objectmore infoBut do not name like
personuser, Admin, visitorcustomer, clientus, usAdmin, cl
productproduct, itemmeal, course, book, etcpro, entity, item
containercart, basketfruits, books, etcbox, bin
databasedatabase, getdbsqlDb, MongoDB etcclassData, dataStorage

Exceptions💥: Since we have built these languages and we are not perfect, so we can now consider some exceptions in class names:

Getters and setters of the class methods actually act like property(not a method), and hence are named accordingly.

(getUser-like methods are getter methods, allowing to access certain properties of the class, and storeData or setUser are setter methods, used to store/ set the property of the class blueprint)

It Does not Mean?🥴

  1. Naming everything with long descriptive names. It will make code bulky and clunky.

  2. Using redundant info like 'UserAge', we can write 'age' instead.

  3. Using slang like product.diePlease() or user.facePalm()

  4. Using inappropriate abbreviations like ymdt for yearMonthDateTime, we can write dateWithTimeZone.

  5. Giving disinformation like

    a. userList = {u1:a, u2:b, ...} it is not a list, but an object. so the name should be userObj or userMap.

    b. allAccounts = accounts.filter(), after filter we get filtered data, not all data. So here name should be filteredAccounts.

Choose distinctive names:👻

Sometimes we encounter situations where we get data which are similar and we have to give similar names. In that situations, we generally go more specific to the variables and name them accordingly.

For Eg; in Analytics we get various info related to daily reports and data.

Don't NameDo this
analytics.getDailyData(day)analytics.getDailyReport(day)
analytics.getDayData(day)analytics.getDataForToday(day)
analytics.getRawDailyData(day)analytics.getParsedDailyData(day)
analytics.getTodayData(day)analytics.getDailyinfo(day)

With the distinct feature, we can easily recognize them while debugging and correction become easy.

Be Consistent with Naming:🤯

Since coding is not a one-day task. It is like a marathon which requires consistency and a bug-free approach. So for that, we have to be consistent with the naming conventions, style of naming variables, functions/methods and classes. If we have used a camelCase convention for naming, we should stick with that.

Many open-source projects give their guidelines related to naming conventions and styles. Before PR we should go through these guidelines to maintain the consistency of the project code.

Understanding with table:

types of consistencycontinue throughout the code
name-casingif used camelCase
if used getUser()do not use fetchUser() or retriveUser() afterwards, stick with get()

Understanding with Example:

class Point:
    def _init_(self, coordX, coordY):
        self.coordX = coordX
        self.coordY = coordY

class Rectangle: 
    def _init_(self, starting_point, broad, high):
        self.starting_point = starting_point
        self.broad = broad
        self.high = high
    def area(self):
        return self.broad * self.high

    def end_points(self):
        top_right = self.startingPoint.coordX + self.broad
        bottom_left = self.startingPoint.coordY + self.high
        print('Starting Point(X):' + str(self.starting_point.coordX))
        print('Starting Point(Y):' + str(self.starting_point.coordY))
        print('End Point X-Axis(Top Right):' + str(top_right))
        print('End Point Y-Axis(Bottom Left):' + str(bottom_left))

def build_stuff():
    main_point = Point(50, 100)
    rect = Rectangle(main_point, 90, 10)

    return rect

my_rect = build_stuff()

print(my_rect.area())
my_rect.end_points()

<Code> snippet got from Academind.com, Thanks Max😍

Can you refactor the code according to the naming convention? In this code, we are taking coordinates from the user for the rectangle to build.

class Point:
    def _init_(self, x, y):
        self.x = x
        self.y = y

class Rectangle: 
    def _init_(self, origin, width, height):
        self.origin = origin
        self.width = width
        self.height = height
    def find_area(self):
        return self.width * self.height

    def print_coordinates(self):
        top_right = self.origin.x + self.width
        bottom_left = self.origin.y + self.height
        print('origin(X):' + str(self.origin.x))
        print('origin(Y):' + str(self.origin.y))
        print('End Point X-Axis(Top Right):' + str(top_right))
        print('End Point Y-Axis(Bottom Left):' + str(bottom_left))

def build_rectangle():
    rectangle_origin = Point(50, 100)
    rectangle = Rectangle(rectangle_origin, 90, 10)

    return rectangle

rectangle = build_rectangle()

print(rectangle.find_area())
rectangle.print_coordinates()

Final Words on Naming:

At last, as we have talked much about naming, we can also say that through proper naming and code structuring, we leave our expression on the code which inspires other coders and programmers to code/ write like this. Your future employees and colleagues can easily understand your code while bug-fixing and appreciate your work as they do not scratch their heads in understanding your code.

Similar to Writers and Novelists, through good and clean code, you can become immortal👼🏽. Your code lives long along with your Name.

😱

🕸

What do we learn from the next blog?

In the next blog, we'll talk about structuring the code, a little bit about Clean-Architecture used in product design and other fields, and How can we comment on the code without bulking its content and making the code understandable and properly structured.

We'll also talk about Code refactoring and formatting( and its types) to enhance the code capability and agility. Through refactoring, we can reduce our code size and make it more readable.