Most software developers know the following phrase:
“ There are 2 hard problems in computer science: cache invalidation, naming things, and off-by-1 errors.“
and they will agree it is hard to give things a good name. Not only is it hard to give classes, functions, and tests a good name, it is also essential to keep source code readable and understandable. In this blog, I will provide some tips and examples for software developers on how they can improve the naming in their source code.
Let the class name explain the problem it solves
If you have a hard time giving a class a good name or if you encounter a bad class name during a code review, try to explain the purpose of the class to yourself. What does it do? Where is it used? Which problem does it solve? By answering these questions, you often deduce a good name for the class.
For example, I once encountered a class like this during a code review:
I did not like the name because this is more than a reference to a case in a file. Why would a reference include a sign date? When I checked the purpose of this class (what does it do, where is it used) I was able to suggest a better name. In the end, the class was used in the front-end in order to display information about the case. That is why I proposed
High cohesion simplifies naming and good naming improves high cohesion
In short, high cohesion means that a class only contains related things with a single purpose. That will most likely lead to compact and logical class names.
As soon as a class has a good name, it automatically helps to keep it cohesive. If you add some unrelated logic, you will probably think, "if I add this logic to the class, the class name will no longer fit," and it will make you think again if adding the logic in that class is the way to go.
For example, if there is a low cohesive class like this:
You would just add another method
sign to this class and lower cohesion even more, while the class name is still covering it all. On the contrary, if the code is organized like this:
You would have added a new high cohesive class
Use domain language
The code you write is most likely for use in a certain domain such as financial, transportation, medical, etc. It is a good habit to use the corresponding domain terminology in the source code. It can be very confusing if the developers use different terminology for the same thing than the other stakeholders.
Most developers write code with English terminology. However, if the domain is very country-specific and the application only uses the local language, I think it is a good idea to keep that terminology untranslated in class names. For example, Dutch law states that in notary deeds, spaces left blank should be rendered unusable for writing prior to signature. The Dutch term for this is 'aflijnen'. This is a very Dutch notary domain-specific term and translating it to English in the source code would be very confusing, so the class name will just use the Dutch term:
Function names should be representative
Function names should be short and correctly represent what the purpose of the function is. If you keep the function short and cohesive, it makes naming easier.
For example, if a function creates a new document every time you call it, the name should be
createDocument. It should not be
getDocument because that function name does not represent that the document will be created each time you call it.
Also, whenever you are following proper naming conventions, you don't require comments to specify what code is doing.
A variable name should not be an abbreviation because that can be confusing. Consider a variable named
cat. Is that a
catalog, or something else?
Do not mention the type in the name
In the past, it could be useful to include the type in the variable name, for instance
. Nowadays, most modern integrated development environments display variable types and automatically flag operations that use incompatible types, making the notation obsolete and obscuring.
result as a return variable name
If a function returns a value, I think it is good practice to just name the returned variable
result. That way it is easy to spot which variable will be returned and saves a lot of thinking about a good name for that function.
Use functional names
A bad test name is often caused by the name describing what the test does instead of describing the requirement it covers.
For instance, compare a test with the name checkR
emoveDocuments versus a test named
documentsOlderThanAWeekAreRemoved. The first just describes what the test does, the latter contains a functional requirement and the purpose of the test in its name.
A good name also helps in determining what happens when a test fails. If it is good, you can get an idea of what is going on without having to look in the test code immediately.
In some programming languages, you can even use spaces in function names, for example, in Kotlin:
Do not prefix the test name with test
If the test framework does not require it, do not start the test name with
test.... It is already clear that it is a test because it is in a test package or class or has an annotation, so that prefix does not add anything.
Naming in general
Make decisions with your team
Agree with your team on things like casing and language. Do you write
Propose an alternative
If you do not like a name, you must always propose a better alternative for it. Naming is hard, so you cannot just say it is bad. Always think and suggest something better.