I've been reading Clean Code by Robert C. Martin, and came across the infamous statement:
Avoid words like Manager, Processor, Data, or Info in the name of a class.
So, naturally, I've tried to factor -Info
out of one of my class names. Now, I've seen all sorts of StackOverflow questions asking about what to do to in the case of -Manager
or -Processor
. I've seen comments suggesting that they can't think of a time when -Data
would be a good class name. Well, in my opinion, -Data
and -Info
seem harder to factor out. Especially, for example in the below class.
I have a Server
class like the following:
public class Server {
//What I would call ServerInfo
private int id;
private String name;
private String address;
private int port;
private int connections;
private int maxConnections;
private int status;
//Bunch of members that aren't ServerInfo, for example:
private ConcurrentHashMap<String, File> files = new ConcurrentHashMap<String, File>();
private List<String> filePaths = new List<String>();
/* ... */
public void start() { /* ... */ }
public void stop() { /* ... */ }
}
There is a HashMap
stored of these Server's information like the following on another remote server:
public class ServerMap {
ConcurrentHashMap<Integer, Server> serverMap = /* ... */;
}
But, this HashMap
only needs to know about what I have said is ServerInfo
above. It doesn't need to waste memory by storing a bunch of variables it will never use. So, a Data class is needed to house these variables.
public class ServerInfo {
private int id;
private String name;
private String address;
private int port;
private int connections;
private int maxConnections;
private int status;
}
And ServerMap
now becomes ConcurrentHashMap<Integer, ServerInfo>
.
The problem is that this obviously violates the rule from Clean Code. I could change -Info
to some synonym, but then, isn't that not really fixing the problem? For example, I could call it ServerDetails
but I fail to see how that is any different than ServerData
or ServerInfo
.
I could redefine Server
in a different namespace, and give it just these members, but that seems even more confusing.
What is the best practice solution to this?
Class namesThey should always be singular. If your class is a container for several notes, then you should find a singular noun to describe the whole thing. I find that using singular nouns usually make it easier to reason about objects and the interactions between them.
While class names start with capital letters, methods should begin with a lowercase letter. Any other words you need as part of the method name will be uppercase. NO SPACES are allowed in the names! Also, since a method is an action (where the class is the blueprint), method names should be verbs.
Class names should be nouns, in mixed case with the first letter of each internal word capitalized. Try to keep your class names simple and descriptive. Use whole words-avoid acronyms and abbreviations (unless the abbreviation is much more widely used than the long form, such as URL or HTML).
I think the point of the statement is to avoid using such overloaded terms like -Data and -Info when it comes to class naming. I don't think it's inappropriate to use something like ServerDetails for the object you're naming. After all, that's what they are isn't it?
If ServerDetails is too generic, ask yourself what kind of info/details they are... In this case they all look network or connection related. How about ServerConnectionProperties or a something similar?
Use the guidelines the author sets forth as exactly that; guidelines. Just keep in mind that there are tons of people with tons of opinions and very few of them apply 100% of the time. You'll go mad trying to apply every 'best practice' to the letter.
I think your looking at the refactoring the wrong way. They correct name (in my opinion) for ServerInfo
would be Server
because that is what the server actually is. When we deal with OOP the "base" object is the object with the data. For example, we wouldnt call a class with username, email, and password UserInfo
or UserData
because the data is implied by the fact that its a class with members.
Obviously, there are some exceptions to this rule. It is common practice to have a ProfileData
object to contain certain less important information for Users.
There are two ways I can think of how I personally would re-factor this server problem.
One is I would rename the base (serverInfo) to Server
and the higher level object to something else like ServerCommands
(its hard for me to find a fitting name because I do not know everthing the class does)
My next suggestion is based on the idea of 'generalization'. The biggest reason we dont want to name classes this why is because it generalizes implied aspects of programming. Just about all classes tend to have "info" and "data" associated. What is this info or data? I would like to quote from the SO subject discussing "helper" and "manager" re-factors.
Reason: A class name like "ThreadHelper" makes people wonder why it's needed and why it cannot just be part of the "Thread" class. Is it actually an adapter or a decorator? If so, name it that way. Is class "Thread" taking too much responsibility already? If so, refactor and give the new class a meaningful name. "Helper" says nothing about what it's doing or how it's helping.
Its all about what is the classes actual intended purpose. If I see a class called serverInfo I might or might not understand what the info is.
I personally would name it ServerProperties
. It might sound like it is just a synonym of info, but its actually more specific. When we think of properties, we think of "one time set up" details that do not change. (or if they do change, it is because we are changing settings). You could also call it ServerSettings
but I personally like properties more.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With