Core Java

My Take On Object Naming

This is one of the most common debates out there. Most people have their opinion about this topic and nobody can actually tell which one is correct. Neither can I, of course, but nevertheless, I decided that I might just share with you my ideas on the matter, throw in my two cents, maybe it will help someone.

When I create a new class, the first thing I do is design its interface (as you know, I believe that any object must implement at least one interface). The name of the interface reflects, usually, what the object is, not what it does or what other obejcts should do with it. There are very few cases where I find adjectives suitable, one of them being Iterable.
 
 
 
 

Tom & Jerry – Jerry’s Cousin, by William Hanna and Joseph Barbera

Then comes the implementation of that interface. Since there may be more implementations in the future, I mostly name the object based on the encapsulated details. So, assuming the interface is HttpRequest, if the first object which obeys this interface uses ApacheHttpClient, its name could be ApacheRequest. Then, another implementation may come, working with a different http client, maybe jcabi-http, in which case the name would be JcabiRequest.

So far, so good, probably nothing new, but here’s the catch: depending on the pattern, the name of my classes won’t necessarily make sense by themselves. For instance, somewhere in one of my projects, you’ll see the following class:

/**
 * Decorator which adds some HTTP headers on the decorated request.
 */
public final class HttpHeaders implements HttpRequest {
    //...
}

It doesn’t look natural by itself, right? Well, it should be clear that this type of request is not supposed to be used “alone”, ever. Its constructor won’t even allow it, since it is supposed to wrap another HttpRequest, maybe another decorator or maybe a concrete request. Can you think of a better name? I believe that, when naming a class, we must also take into account how it is going to be used, in what context or pattern – if the names make sense when all of them are put together, then you are fine. Adding useless nouns will only end up making noise.

HttpHeaders would be used as follows:

   Map<String, String> headers = ...;
    HttpRequest request = new HttpHeaders (
        new Get(URI.create(...)),
        headers
    );

Furthermore, I hate useless suffixes. Let’s take the most glorious example: “Factory”. Have you noticed that, when an object is tasked with creating other objects nothing matters anymore? The context, the business, the domain, nothing! That poor object’s name must have the suffix “Factory”, otherwise the code just won’t work.

I do have factory objects in my code, but the word “factory” is not present anywhere. The project is a chatbot and one of the top-most abstractions is the “Knowledge”, something that the bot knows how to do. Each implementation of Knowledge creates a tree of Steps which represent it – the bot needs to take one or more steps in order to fulfill any command. What I called “Knowledge” is actually a factory object, because it creates other obejcts, those Steps. Here is how the assembled code looks like:

final Conversation talk = new Conversation(
        new Hello(
            new RunScript(
                new Confused()
            )
        )
    );
    talk.start(command);

Conversation, Hello, RunScript and Confused are all implementing Knowledge and they work together in a cascade mechanism, in order to find the proper steps to be executed. The snippet above translates to the following words: “A conversation is started, the bot can say ‘hello’, run some scripts for you or it may be confused if it does not understand the command”.

Now here is the same snippet of code, with a more common naming:

 final StepsFactory factory = new ConversationFactory(
        new HelloFactory(
            new RunScriptFactory(
                new ConfusedFactory()
            )
        )
    );
    factory.getSteps(command);

Which one is better? They will both work the same, it’s just about readability. To me, it’s like a finished building vs a building which still has the construction scaffolding around it – nobody wants to know how the house has been built, all the scaffolding and instruments used, that is not important. Instead, everyone is eager to see the final construct and they should understand what it does without being clear what’s been used to achieve it.

Another example of naming:

Log log = new WebLog(
    new LogFile("/comdor/ActionLogs", this.id),
    "https://webapps.amihaiemil.com"
);

Why WebLog? Because the encapsulated Log will ultimately be presented to the user on the web UI. When calling log.address(), the String “https://webapps.amihaiemil.com” will be concatenated with the file’s name to form a valid URL. Here is the WebLog class, you can also see that the encapsulated variable of type Log, the one which will be displayed to the user, is named “onServer” – because it is the log file which, in the end, will be fetched from the server.

This is pretty much the idea of how I handle naming. And, of course, I always write JavaDocs (Maven central won’t even allow you to publish anything without them) so, if a name is not good enough, the JavaDoc on top of it will always shed light for you. What do you think? What naming conventions do you use?

Published on Java Code Geeks with permission by MIhai Andronache, partner at our JCG program. See the original article here: My Take On Object Naming

Opinions expressed by Java Code Geeks contributors are their own.

Mihai Andronache

Mihai is an experienced Java and JavaEE developer. His main interests are: clean OOP, code maintainability and testing. He is the creator of http://comdor.co and http://charles.amihaiemil.com"
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

4 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Mark B
Mark B
6 years ago

That’s not a factory.

Mihai A.
6 years ago
Reply to  Mark B

Well, I would say it is. It’s not a classic one, being fully encapsulated, it doesn’t take any config objects in its constructor. Plus, they are combined in that cascade mechanism But, in the end, its task is to create another object for us, so what else would you say it is?

Jonathan L
6 years ago

I would rather sacrifice a little readability in exchange for knowing what an object’s role is. In your example, I would have no idea it is performing a factory operation and wouldn’t use it in my production code.

Mihai A.
6 years ago
Reply to  Jonathan L

> what an object’s role is Here, this is the difference in our thinking: I first think “what *is* an object” and only then I think “what should it do, how should it work with the other objects?” — in our case, the name is Conversation because that’s what it *is*, a conversation that the bot has with the commander (started because of an initial command). If the name is not suggestive enough, there are JavaDocs + unit tests that should tell you exactly what an object is and what it does/how it should be used. And in this particular… Read more »

Back to top button