Saturday, September 13, 2008

Thoughts on naming methods and classes

This may seem like a trivial thing to discuss, but I actually think is quite important because the name of a method or class can change how you think about a particualr piece of code. For me, there are at least two ways of naming a method:

  1. What it does, e.g., donaldDuck = ducks.findByName("Donald"). This is probably the name you come up with when you realize that you need the particular method ("How do I ...? Ah, I need to find the duck named 'Donald'. Then I can ...").
  2. what it returns or how it will be used, e.g., donaldDuck = ducks.named("Donald"). I usually come up with this type of names when I think about the contexts the method will be called from. That is, how the code will look when you read it.
Let's take a concrete example to illustrait. Assume that we have a class Bag representing a set of objects. This class have a constructor taking a single Class argument that is the type of the objects the Bag contains. Thus, to get your self a new fancy bag you do:

final Bag<Apple> appleBag = new Bag<Apple>(Apple.class);

"Yuck", you think to your self, "that's a lot of code just to get one lousy bag". To remedy this, you decide to write a static factory method in the Bag class. How should should you name this method? 

  1. What it does: static <T> Bag<T> newBag(final Class<T> contentType)
  2. How/where it will be used: static <T> Bag<T> of(final Class<T> contentType)

Now, to put this into context:

01 void Bag<Appple> chooseStylishBag() {
02   if (isOutOfStule(oldBag))
03     return Bag.of(Apples.class);
04   return oldBag;
05 }

I think line 03 reads very nice. It's short and to the point, and does not expose implementation deatils, etc.

All is good with that bag buissness -- or at least so you though. However, after a few days a fellow programmer says that (s)he does not like the name of the method because it is not clear that it create a new empty bag. You respond 'well, you could just read the documentation for the of method'. You have't even completed that sentence before your colleague replies 'good code should not need documentation! It should be self-documented!'. (S)he is of course right. What to do?

Let's go back and rewrite the chooseStylishBag method such that it is clear that it returns an empty Bag.

01 void Bag<Apple>> chooseStylishBag() {
02   if (isOutOfStule(oldBag))
03     return EmptyBag.of(Apples.class);
04   return oldBag;
05 }

That is, we've moved the of factory method to a separate factory class that is called EmptyBag. Your angry colleague does not complain any more. All is calm again.

No comments: