?

Log in

Naming Conventions, Part One

Chapter X: Naming Conventions, Part One

This is simple common sense stuff here. Classes that represent business objects should be named nouns. Classes that perform actions should be named verbs. For example:

beans.UserProfile
pages.SetName

Clear? Good. Now let me explain why those names are actually bad. Suppose you need another business object to represent the user's dental records. Following the prior naming scheme you now have:

beans.UserProfile
beans.UserDentalRecords

Likewise, what if you want to create pages to set the user's e-mail and password?

pages.SetName
pages.SetEmail
pages.SetPassword

Seeing a pattern here? I hope so. The prefixes "beans.User" and "pages.Set" are becoming rather redundant. Now what if you need some utility classes as well:

pages.SetName
pages.NameChecker
pages.SetEmail
pages.EmailValidator
pages.SetPassword
pages.PasswordGenerator

Now you've got a mess on your hands. What's the solution? Write this down, because it's my golden rule of naming conventions: use common name elements as the package structure. What does that mean in layman's terms? The name commonalities like "User" and "Set" become sub packages, and likewise "Name", "E-mail", and "Password" become sub-sub packages, giving you something like this:

beans.user.Profile
beans.user.DentalRecords

pages.name.Set
pages.name.Checker
pages.email.Set
pages.email.Validator
pages.password.Set
pages.password.Generator

As a rule of thumb, whenever you create a class with a compound name, ask yourself if one or more parts of the name would make more sense as part of the package structure.

Do you think that's too anal? Well I'm just getting warmed up.

Why does the name package have a "checker" and the e-mail package has a "validator"? What's the difference between checking and validating? Maybe on the inside, quite a bit differs, but on the outside it's an ambiguous naming conflict. Any class that checks, validates, confirms, or any other synonym thereof should share a single global name.

Have I crossed the line from strict to insane? Keep reading.

Personally, I would go one step further with the prior example like so:

beans.user.records.Dental

Now if somewhere down the line I have to support some other type of user records, like Psychiatric or Orthodontic, I'm good to go with a nice clean package structure.

beans.user.records.Dental
beans.user.records.Psychiatric
beans.user.records.Orthodontic

One of my biggest pet peeves, which happens to be a favored habit of my partner in crime at my current venture, is naming classes redundant of their packages. For example, "recipe.RecipeList". That drives me up a wall. This example should, of course, be "recipe.List" since there's no other logical lists to place in the recipe package.

Now some of you might be foaming at the mouth and waving your fists in the air and screaming, "What about naming conflicts!?" Yes, if you have a "recipe.List" class and a "book.List" class and both are referenced from another class, that for example manages a mapping of which recipes are in which books, then you can't simply reference either "List" class without the compiler complaining that it doesn't know to which list you are referring.

Thankfully, some clever coders over at Microsoft thought this through and within the .Net environment you can specify which list you mean by prefixing just enough package information for the compiler to figure it out. So if the recipe list class is in the package "com.mycompany.cookbook.recipe.List" you only have to use "recipe.List" when referencing it (assuming you have the recipe package imported or it's relative to the referring class). Java, however, requires the entire package path. Yes, it's annoying to have to type it all out and it makes the code look a lot more cluttered, but in my book (ha, this is my book) it's a small price to pay for a cleaner, more logical, and more manageable package structure.

Programmers hate to write documentation. Well, that's the cliche anyway. For me, I don't hate writing it, I just hate the fact that it's always out of date. In today's world, unless you work on an incredibly strict project like a NASA system, your code is changing daily, and in some cases rather drastically. Architectural documents, explaining the overall organization of the system, are the most accurate for the longest period of time. Functional documents, explaining the logic behind an API, last longer the more vague they are. API documentation is the absolute worst; it's wrong as soon as you write it.

This dichotomy of documentation and code is why naming conventions are all the more important. The cleaner the package structure and the class names, the more "self documenting" the code base is. When I see a class named "recipe.List" I know that it manages a list of recipes. Likewise I know that "password.Set" will set a password. Likewise I know that "user.password.Set" sets a different password than "system.password.Set". The more I can ascertain from a quick glance of the code, the less I need to spell-out in the documentation.

Copyright (c) 2003 Thomas E. Davis, All Rights Reserved.

Comments

(Anonymous)

Clash of the namespaces

import java.util.Set;
import recipe.Set;
import user.Set;

public void foo() {
Set recipes = new Set();
Set users = new Set();
}

You think this is obvious let alone compiles? You must be kidding right?!!!

So now you want me to write it like this:

import java.util.Set;

public void foo() {
recipe.Set recipes = new recipe.Set();
recipe.Set users = new user.Set();
}

Interesting...I'll have to dwell on this a little more.

Re: Clash of the namespaces

Thank you for pointing out two areas of confusion I need to clarify:

1) You can't import the classes of the same name individually in Java.

2) The Set class is supposed to be an action not a collection, so you wouldn't instantiate it.

(Anonymous)

You want what?

It's a good thing we don't work on the same project - this convention would drive me insane. Every list class is named List? You're writing in Java - best to work with the language rather than against it.

I find that when using IntelliJ, redundant package names hardly even matter. You never need to type a package name - just type the class name and it figures it out (giving you a chance to resolve the redundancy if there is one.) And the only place package names are listed are in the imports list at the top of the file, so they're nicely out of the way.

A kindred spirit?

June 2005

S M T W T F S
   1234
567891011
12131415161718
19202122232425
2627282930  
Powered by LiveJournal.com