Welcome to the first part of the clean code series. This series will be highly inspired by and sometimes embarrassingly copied from the Clean Code book by Robert C. Martin (Uncle Bob). I highly recommend reading the book. This series is nowhere near to the original book.

The book has a lot of code examples, and most of them are provided in Java. I will not go through all the code examples, but if I do use some, I will translate or make examples using Python.

What Is Clean Code?

Clean code should have:

  • Full test coverage
  • Complete error handling
  • No duplications
  • High expressiveness
  • A minimal number of entities such as class, function, methods, and …
  • Performance close to optimal
  • Minimal dependencies on third parties

Meaningful Names

Names are the smallest building block of code. Names are everywhere: Function, class, file, component, and container all have names. Names are also the basic building blocks of clean code. There are some hard and fast rules to a good name.

Use intention-revealing names

A good name should answer only three questions.

I know it sounds simple, but it takes a lot of time to get a good name. However, it will save more than that in the long run.

A name should not have comments to express its intentions. Look at this example:

# Dirty Code d = 100 # elapsed time in days 
# Clean Code elapsed_time_in_days = 100

In the first case, you need to go through the comment. That’s okay for one time. But whenever you use the variable d, you will have to come to the initialization to get the intention of the variable. But the second case, elapsed_time_in_days, is expressive on its own.

Don’t give your variable a one-letter name. One-letter names are never expressive. They fail to reveal their intention. There are some exceptions, like the letters ij, and k in the for loop. However, never use a small letter l (el), a capital letter I (eye), or a capital letter O (oh) as a name because programmers tend to confuse them with one and zero, respectively.

Avoid disinformation

Avoid names that are platform-specific, like htop andhp.

Don’t use names with small changes like dataset_generator_for_cat_with_user_mobile_1 and dataset_generator_for_cat_with_user_mobile_2. In this case, you don’t get the difference until the last letter, and most of the time, you’ll ignore that difference.

Make meaningful distinctions

There should be enough distinctions in the variable naming. Don’t just append a number if you have a variable with the same name in the scope: a1a2 is the opposite of intention-revealing.

Don’t use names with similar meanings. For instance, product_data and product_info do not have a proper distinction. Just by looking at the name, you can’t assume the intentions of these two variables. These are called noise words. Some of the other noise words are aan, and the.

Don’t append variable type to the variable name. Make the variable name so expressive that you can understand the type uniquely by the name alone. For instance, account_name can never be a floating-point number. It must and should be a string. There are some exceptions, like id, which can be a string or a number. But then that convention should be followed all over the project so the programmer working on that project will know if the id is a number, a string, or something else.

Use pronounceable names

If you can’t pronounce it, you can’t discuss it without sounding like an idiot.

Sometimes a short example is better than a lot of text:

# Poor Name gen_ymdhms = "1591442356268" # Generation year, month, date, hour, min, sec 
# Good Name
genration_timestamp = "1591442356268"

Use searchable names

Avoid using one-letter names as much as possible. If you need to use a one-letter name, use it only within a local scope rather than over a global scope.

Avoid using common words like sumtemp, or flag as they seem to be used by a lot of methods and classes and are thus not search-friendly names.

Avoid encodings

Avoid using encodings like Hungarian Notation or Member Prefixes. They were used before when the IDE was not as smart as it is now. Current IDEs are smart enough to give us suggestions about the type or the member variable of a class. We don’t want to clutter our brains with more information.

On the other hand, language-specific encodings should be maintained throughout the project, such as snake_case in Python and camel case in JavaScript.

Avoid mental mapping

Programmers indeed are really smart. But code is not a place to show off your smartness. You can obviously remember that r is the variable name for a URL with the host and scheme removed. But the person who will be reading your code would not know that mental mapping. Use names that properly express the intention of the variable.

Class name

Class name should be a noun or noun phrase. By design, classes are an encapsulation of the same type methods and variables, thus they should have a common name. Classes should not be a verb in any way.

Function/method name

Functions should be a verb or verb phrase. By design, a function should have only one responsibility. If the name is anything other than a verb, then either you are naming it wrong or there are some problems in the architecture.

Pick one word per concept

Avoid using different but similar words to define the same concepts. For instance, don’t use fetchget and retrieve in the same project for the same responsibility.

Don’t use the same word for different concepts

Avoid using the same word for totally different concepts. When you are intending to follow the previous rule, you will end up with a lot of variables with the same name. Perhaps add is used throughout the project to add or concatenate two existing values. But if we use it to append a new value to an existing variable, it would be confusing. append seems a more reasonable name for this method.

Use solution domain names

Your code will be read and maintained by programmers, so it’s okay to use solution domain names. For example, in the machine learning context, data_generator is a good name. Whoever sees this name will know that it’s a data generator that is an iterator to loop on.

Use problem domain names

If there are no solution domain names available, then use a domain-specific name. In that case, the programmer can ask a domain expert about the meaning.

Add meaningful context

As a programmer, our first duty is to choose names that are as expressive as they can be. But sometimes it’s not possible to give context with a variable name. In that case, first try to enclose the variables in a meaningful class or function. For example, namecity, and district should be enclosed in a class name Address. If that’s not possible at all, prefix the variable with the name of the context. But remember, that is a last resort, so use it after meticulous thinking.

I know that’s a lot of dos and don’ts for a simple thing. But trust me, this is the toughest problem I’ve faced in my small software engineering career.

Leave a Reply