a blog about things that I've been thinking hard about

The "Name of a Name" Pattern

15 November, 2005
names of names ⇒ pointless indirection

They tell us: "Don't hard-code your constants"

But what if a constant is a string value which names something?

What do you call it?

FREDS_NAME = "fred" ????

A Code Example

Have you ever written code like this?

public static final String FREDS_NAME = "fred";

This code (written in the Java programming language) is an example of defining a constant, in this case a constant string. If you used the string "fred" throughout your code, people reading your code might wonder what it referred to. By defining the constant FREDS_NAME, and using it throughout your code where you would otherwise have used "fred", you resolve the mystery. If necessary, further clarification can be added in a comment, like so:

/** Fred's name **/

public static final String FREDS_NAME = "Fred";

(Note the convention that constant identifiers are usually given in all upper-case.)

One of the important advantages of using defined constants instead of raw values is that if the value changes, you only need to make the change in one place. For example, if Fred changes his name to James, you can change your constant definition to:

public static final String FREDS_NAME = "James";

There is no need to change the code where the constant is used, and this helps to prevent changes from rippling through your code.

A More Realistic Example

The above example was a little contrived, but I wanted to emphasise the use of the Name of a Name pattern. A more realistic use of a name in a Java program might be the name of a column in an SQL database.

For example, you might have an expense column, from which a value is retrieved, as in:

float expenseAmount = resultSet.getFloat ("expense");

Once again, we can move the raw value "expense" into a constant definition, like this:

public static final String EXPENSE_COLUMN_NAME = "expense";

...

float expenseAmount = resultSet.getFloat (EXPENSE_COLUMN_NAME);

And if, for some reason, the database owner decides to rename the column, for example to cost, then you need only make one change in your program, i.e.:

public static final String EXPENSE_COLUMN_NAME = "cost";

Objections

There is one objection to the use of the "Name of a Name" pattern, which is that the following code:

public static final String FREDS_NAME = "James";

doesn't make sense. If you read it as a sentence in English, it says that "Fred's name is James". Which just isn't true. And everywhere that you refer to James in your code, you refer to him using the defined constant FREDS_NAME, which would lead anyone reading your program to think that you were referring to someone called "Fred".

A similar problem will happen in the database column example. If the database owner decided to rename expense to cost, they probably had a good reason for doing so, and this good reason is probably that "cost" is a more accurate description of what the column means. In which case, you probably want to call it "cost" in your program as well.

Conclusion

The conclusion is that the "Name of a Name" pattern isn't really a pattern at all, it's an anti-pattern. The symptoms of this anti-pattern are:

To avoid this anti-pattern, you have to stop pretending that the name of the name is distinct from the name itself. And if you want to use a programming language identifier in one place, and quoted string data in another, you should use an automatic facility to translate from one to the other. In practice this means that you should use a dynamic programming language which is dynamic enough to convert internal identifiers to and from external string identifiers.

With a bit of effort this can happen in Java, but it's much easier in languages like Python and Ruby. For example, in the application framework Ruby on Rails, the ActiveRecord pattern automatically translates table names into class names and column names into class field names. If a database column name changes, the corresponding identifier in the Ruby code will also change, and you may have to edit your code in various different places accordingly. But at least all your names will continue to mean what they say they mean.

Vote for or comment on this article on Reddit or Hacker News ...