Paul Haahr / Essays / Java Style / Naming

Naming

Use consistent naming conventions

A good name is consistent with other names in a program. If an access method is named getFoo, don't call the method which changes the value fooSetter or the method which reads the ``baz'' value anything other than getBaz.

Use names you can pronounce

People talk about programs. It's easier to talk about code if you can pronounce the words inside of it. And, at least for those of us who talk to ourselves when we write code, it's also easier to think about programs if they're easy to read aloud and pronounce.

My business partner and I work in offices separated by about ten miles and a large body of water. We communicate mostly by email, but have done debugging-by-telephone a fair number of times. Without names we could say easily, that would have been much more difficult. (As is, case sensitivity is an issue. How do you pronounce CodeStream differently from codestream?)

Don't use abbreviations

I dislike most use of abbreviations and shorthands in names. Programs, like prose, are meant to be read, and pervasive use of artificially shortened names makes text harder to read. In particular, dropping vowels to shorten a name does not make it more readable.

There are exceptions to this, of course, especially for acronyms in widespread use in the relevant problem domain. So it seems perfectly reasonable to me that Sun uses ``URL'' as part of names in the java.net APIs and that a class in our compiler is called SSAVariable, because everyone working on modern compilers knows that ``SSA'' stands for ``Static Single Assignment.''

Types provide good roots for variable names

I hate the so-called Hungarian notation favored by Microsoft and many Windows programmers. This style encodes redundant type information in dense, unpronounceable prefixes for variable names and interferes with simple readability. Of course, its advocates disagree.

Often, it's a good idea to use a variables type as part of its name. For example button and resetButton are good names for instances of the Button class.

I strongly dislike the coding style which uses aButton or theButton as generic names. ``A button'' seems to vague to me, ``the button'' too precise, and in neither case do I find the extra information, if any, provided by the article to be worth the bother. (Using variables named both aButton and theButton in the same context seems particularly egregious.)

In Java, interfaces and abstract classes are often more suitable names for objects than concrete classes. I'll often use stream as the name for a local variable or parameter which is a PrintStream or DataInputStream, and depend on context for figuring out which one I mean. If there are two streams being used in a particular context, I'll try to use a prefixes that indicates the purposes of the streams, such as inputStream and outputStream (or just input and output), or dataStream and controlStream.

Good names aren't necessarily long names

For a loop index, i is usually a better name than loopIndex. In general, local variables should have short names because there is an obvious context for them, instance variables or structure members have less context so they may need longer names, and global names (only classes in Java) may need more in their name to make up for their lack of context.

Steal names from external sources

I'm often coding up algorithms from research papers or textbooks; not everybody does this all the time, but it's usually the best way to go in a well-researched field like compilers. When doing so, I try to pick variable names which correspond to the names used in the published material, then cite a reference in a comment. Thus, anyone reading my code can go back to the original source and directly see the mapping to my code.

In addition to domain-specific sources, good names can be found in writing or folklore on programming methodology. For example, the names of patterns in the ``Gang of Four'' Design Patterns book provide excellent roots for class or interface names, because they've become part of a common vocabulary for object-oriented programming. Thus the name of the class java.net.ContentHandlerFactory from the core Java libraries immediately tells the reader that this class uses the ``Abstract Factory'' creation pattern, which leverages a lot of meaning from seven characters in the name.

Use sensible parts of speech

Parts of speech provide a good guide to how a word should be used, and this can be leveraged when naming entities in a program. When picking a name for a thing, use a noun. When looking for an action, use a verb. Typically, this means that classes and variables will be nouns and method names will be verbs or verb phrases. But, classes or objects which fit the ``strategy'' or ``command'' design patterns might be best named with verbs. Similarly, an accessor method may simply name a noun corresponding to the value it returns.

Adjectives often make good names for interfaces and abstract classes - classes which implement or inherit from the adjectival base have the named property. Adjectives are also potential names for boolean fields and methods.

Finally, plurals are often good names for instances of collections, such as arrays or vectors.

Some examples of names in these various categories from the core Java libraries or the Redshift compiler, grouping noun phrases as nouns, etc., are:

part of speech constructs examples
singular nouns class, interface Node, Reader, AssignableVariable
variable, field node, reader, variable
accessor method definingClass
exception AccessViolation
plural nouns variable or field holding a collection writers, sources
verbs method append, getSource, deleteIfEmpty
strategy class FuseComparisons, CombineBlocks
command class AddInt, GetField
adjectives interface Cloneable, HasSuccessors
boolean method or field usesHandles, cacheable
``is'' + adjective boolean method or field isReady, isPublic

Use names with a positive sense

Martin Fowler, in his excellent book on Refactoring, makes a mistake in the example for Consolidate Conditional Expression (240) by confusing the positive and negative forms of a name.

Often names, especially those of predicates or boolean values, can be chosen either in a positive (e.g., isValid or contains) or negative (isInvalid or doesNotContain) form. Always use the positive form (and ensure that the implementation matches the name). The negative form can always be constructed by using the logical negation (!) operator. In contrast, deriving a positive form by negating a negative sense name creates a potentially confusing double negative.

Name all magic numbers

Many programs need to use numeric constants. It is almost always best to assign names to these values rather than using raw numbers. The often cited reason is that the number may change and localizing the usage of the actual constant value makes it possible to modify the program without hunting in many places for the incorrect value.

Preparing for a program's evolution is a good idea, but, to me, an even more important reason for naming constants is that it's very hard to tell what a given integer means (number of eggs in a package? hours on a clock face?) and using a name provides context. Thus, even when working with quantities that really will never change, using an expression like months.length is better than the raw number 12.

An extreme version of this rule says ``name all constants other than zero or one.'' The exceptions can probably be safely generalized to include two and negative one, but it's a good way to think about the principle.

Be willing to change a bad name

Bad names are often obvious: they're the ones which are hard to remember or don't seem to describe their purpose well. Until an interface is frozen or exposed to a body of users, it's a good idea to repeatedly go back to the names that bother you. When a name is good, it probably won't stick out at you. Eventually, you'll find a better name.

To some degree, Java works against the ability to change names, because of the connection (in most development environments) between class names and source file names. When you come up with a better name for a class, you need to rename the source file containing it, which may or may not be an operation that is well-supported by a source-control system. That leads to friction in changing names, where it should be a smooth operation.


Back: Typography
Next: Class structure