Naming things in coding is always something of great debate, and important to give appropriate consideration, because it greatly influences readability. And readability -as we all know- is the second most important aspect of source code, the most important one being that it should work of course 🙂
There are competing naming styles; camelcase starting with or without a capital, underscores, all caps, etc. But I do not want to get into that, to each his own. Or her own. Personally I prefer the Java style, with the difference in naming between classes (CamelCase) and methods (camelCase), so I’m going to use that for the examples here.
What I would like to talk about is the concept of a “default verb”. As a rule of thumb class names are nouns; they’re a Factory, or a Singleton, or Person. And methods perform actions on classes, so their name should start with a verb; getName, createInstance, build, walk, …, they do something.
But for some classes there is such a thing as a default verb, which can improve readability of the code. A good example is the builder pattern. Suppose we have a Person builder, which -when adhering to the naming rules- should result in code like this:
Person person = new PersonBuilder() .withFirstName("Donald") .withLastName("Duck") .withAge(90) .addTrait(Trait.Temperamentful) .build();
In Java a setter should have return type void, so a wither often is used if the setter should return “this”. And yes, we can discuss if with is a real verb, but bear with me.
The with is repeated for every value that is assigned, which makes is a bit of a scaffolding. A builder’s primary business is assigning values, so we could consider with (or set) the default verb for a builder. And thus remove it from the method’s name where appropriate.
Person person = new PersonBuilder() .firstName("Donald") .lastName("Duck") .age(90) .addTrait(Trait.Temperamentful) .build();
Personally I like this notation. And the concept of a default verb explains why it is okay to omit the verb in the name of some, but not all methods.
Another situation where the verb can be missing from the method’s name is when it is implied. This is something that can be seen in natural languages as well, when part of a sentence is left out. Good examples for implied verbs are toString() and asList(). It is pretty obvious that the implied verb is something like convert.
Implied verbs have to be obvious based on the method name only, there can only be one class level default verb. If we take the example again, and assume that the add in addTrait() can be implied because it also is some kind of “set”, you’d get this:
Person person = new PersonBuilder() .firstName("Donald") .lastName("Duck") .age(90) .trait(Trait.Temperamentful) .build();
Basically this works, but the differences in behavior between age and trait are not clear in this way. Set is not the same as add, as the example below illustrates.
Person person = new PersonBuilder() .age(90) .age(80) .trait(Trait.Temperamentful) .trait(Trait.Impatient) .build();
The age value is overridden, while the traits are combined. The method names do not obviously imply a verb, and there can only be one default verb, so this is not a good idea. The add should stay in addTrait.