What follows are simple rules to create good naming - Naming is used everywhere from variables to function to files to directory etc..

Use Intention-Revealing Names:

It is easy to say that names should reveal intent. Choosing good names takes time but saves more than it takes. The name of variables, function, class should answer all the big questions:

  • Why it exist
  • What id does
  • How is it used
process_file.py -
for k in values.keys():
	found = False
	for kk in PROCESS_MAPPING.keys():
		if k == kk.lower():
			if k in PROCESS_INT:
				try:
					values[k] = int(values[k])
					if (k == "value" or k == "max_value") and not 0 <= values[k] <= 100:

This here would be a concrete example of what not to do in naming - It is hard to tell what this code is doing but they are only 2 variables and no complex logic to this function. Working with ‘better’name variables would make the code look like this:

process_file.py
for attribute_name in file.keys():
	are_ints_processed = False
	for file_model_name in MAPPING_REMEDIATION_TO_MODEL.keys():
		if attribute_name == file_model_name.lower():
			if attribute_name in INTEGER_FIELD_IN_FILE:
				try:
					model[attribute_name] = int(model[attribute_name])
					if (attribute_name == "value" or attribute_name == "max_value") and not 0 <= model[attribute_name] <= 100:

With these simple name changes I feel like this function is easier to understand.

Avoid Disinformation

Programmers must avoid leaving false clues that obscure the meaning of the code - If you call something accountList then it should be a list we often this something like this in our code with for example id/identifier:

my_model.py
query = query.filter(MyModel.identifier == mymodel_id)

Here mymodel_id is misleading because we’re actually looking for the identifier and top of this an id is usually an int while an identifier could be anything (string or integer).

We should also be aware of using names that vary in a small ways -

deletion_service.py
def get_model_link_to_delete_ba(...):
	...
def get_model_link_to_delete_bf(...):
	...

A single letter changes on those functions which makes it hard to see.

Spelling is also considered an information - We often can make typing errors in our code like user_dashobard instead of user_dashboard

Make meaningful distinction

Programmers create problems for themselves when they write code solely to satisfy a compiler or interpreter. For example writing klass instead of class because class is already taken - Given a standard contexts structure with repo/service/domain we can often encounter:

contexts/myobject/repository
from contexts.model.domain.my_object import MyObject
from contexts.model.dto.model_my_object import (
MyObject as MyObjectEntity,
)

We’ve decided to let the domain object MyObject as MyObject but we did import our model ‘as MyObjectEntity’ which makes a meaningful distinction in my eyes.

Another type of bad distinction is to use noise words such as Info or Data - We often see this in codebases when some object/function/class are not directly used - For example some class name when managing endpoint will never be called:

@endpoint('path')
class MyEndpoint:
def get():
	...

The class MyEndpoint would never be directly called which is an easy copy-paste and forget about it issue. If this issue keeps happening it might be harder to fix as their are no clear indication on what this endpoint is doing.

There is however nothing wrong on using prefixes like ‘the’ ‘a’etc..

Use pronounceable names

Humans are good at words. A significant part of our brains is dedicated to the concept of words. If you can’t pronounce it you can’t discuss it without sounding like an idiot. New developers had to have the variables explained to them - genymdhms (generation date, year, month, day, hour, minute, and second)

Use searchable names

Single letter names and numeric constants have a particular problem is that they are not easy to locate across a body of text. try look for ‘i’ in any codebase..

For example grepping for MAX_CLASSES_PER_STUDENT is easy while grepping for ‘7’ is nearly impossible.

Avoid encoding

We have enough encodings to deal with without adding more trouble for us.

Hungarian Notation

I’m not familliar with Hungarian Notation and the book doesn’t really explain it imo - Here some quick explanation extracted for somewhere else:

Hungarian notation is an identifier naming convention in which the name of a variable or function indciates its intention, kind or type

Basically it means prefixing the variable/function name with its type - str_get_user_name()

Member prefixes

You classes and functions should be small enough that you don’t need to use prefixes.

Interfaces and implementations

Lets say you have an abstract factory for the creation of shapes - Legacy whise most people would of called the factory ShapeFactory and the implementation IShapeFactory, the I is a distraction at best and too much information at worst. Calling ShapeFactoryImp is prefereable to encoding the interface.

Avoid Mental Mapping

Readers shouldn’t have to mentally translate your names into other names they already know. We do this very very often in complex application where the business language is tied to the technical language - or places that are use to this - lets say you are working in a dishwasher application with bad pratices you can imagine having code like:

if dw.loaded:
	dd = True

Which would stand for:

if dishwasher.is_loaded:
	dirty_dishes = True

While this example might seem far fetched I think we can all get example like this but we are use to seeing them in our codebases.

We shouldn’t need to do this mental gymastic. Clarity is king.

Class Names

A class name should not be a verb but a nouns/phrase like Customer, WikiPage,Account - Avoid word like Processor, Data, Info etc..

Method names:

Methods should have verb/ verb phrase names like postPayment, deletePage

Don’t be cute:

If name are too clever they will be memorable only to people who share the author’s sense of humor. Will they know the function named HolyHandGrenade is supposed to do? Sure its cute but maybe DeleteItems is better in that case.

Pick One Word per concept

For example retreiving something should be called either retrieve, get or fetch for example but cannot be all three

This makes it hard to remember which methods names goes with which class. Likewise it is confusion to have a controller, manager and a drive in the same code base.

Don’t Pun

Avoid using the same word for two purposes.

Our goal as authors is to make our code as easy as possible to understand. We want our code to be a quick skim not an intense study.

Use Solution Domain Names

The people reading your code are programmers so we can go ahead and use computer science terms, algorithm names, pattern names etc.. For example what programmer would not know what a JobQueue is?

Use Problem Domain Names

When their is no programmer-eese name for what you’re doing we should use a name from the problem domain. The code that has more to do with problem domain concepts should draw names from their.

Add Meaningful Context

There are a few names which are meaningful in and of themselves. You need to place names in contexts by enclosing them in well-named classses, functions or namespaces. When all else fails prefixing might work. The author gives an adress example - If you see firstName, lastName, street, houseNumber, city, state you would assume that they form an adress - Now what if in the code you only see the ‘state’ part? By prefixing all of these variables with ‘addr’ you make it clear to the reader that state is part of an adress.

Don’t add gratuitous context

For example in an application named Gas Station Deluxe it is a bad idea to prefix every class with GSD. Everytime you type G your IDE will give you a mile long list of every class in the system.

Shorter names are generally better than longer ones, as long as they are clear. Add no more context to a name than is necessary.

Final words

The hardest thing about choosing good names is that it requires good descriptive skills and a shared cultural background. People are also afraid of renaming things for feat that other devs will object. However we don’t memorize those function names anyway most of the time our IDE do it for us.