Naming things well is a huge deal. It’s hard and it should be hard. Poorly named things can mislead/confuse people, slow down velocity, and cause poor separation of concerns in design/implementation. On the other hand, well named things will allow others to correctly understand the function and use of an object, as well as encourage correctly placing new functionality in the proper object or layer.
I have been guilty of all of these, and have had to refactor my mistakes out of code. The worst offender in lazy naming is the “SomethingManager”. It sounds like it should mean something, but in practice it’s overused to the point of obscurity.
Alan Green rails against the meaninglessness of SomethingManager and makes several good points:
How many classes do you come across named ‘SomethingManager’? Any decent sized commercial system seems to have plenty – SessionManager, ConnectionManager, PolicyManager, QueueManager, UrlManager, ConfigurationManager, or even, sadly, EJBManager.
A quick look at the dictionary entry for “manager” and “manage” gives at least ten different meanings – from “to make and keep compliant” through to “to achieve one’s purpose”. I remember one day when the receptionist briefly retitled herself as Switchboard Manager. The common semantic to all these definitions seem to be a vague “looks after stuff”.
This imprecision makes Manager a bad word to use in naming classes. For instance, take a class named “UrlManager” – you cannot tell whether it’s a pool of URLs, manipulates URLs or audits the use of them. All the name tells you is that this is not a URL, but it does somehow work with them. On the other hand, the name “UrlBuilder” gives a much better picture of what the class does.
This lazy way of naming leads to all kinds of confusion. Usually people use “SomethingManager” because they have not fully defined what this thing is supposed to do and it winds up being a bucket for things that don’t really fit somewhere else. Avoid SomethingManager in favor of something more explicit, like SomethingBuilder, SomethingPool, SomethingSupervisor, SomethingTransformer, SomethingShepherd/SomethingWrangler, SomethingGatekeeper, or SomethingUtilities.
A sibling of the SomethingManager is the SomethingDAO. Often we are not sure if this should be a factory of the “Something” or a set of utility classes for the something, or the only access point for the something from a datasource. Sometimes it’a all of those things. Be careful with the separation of concerns and be consistent in your usage of the SomethingDAO suffix.
Another sibling is SomethingEngine. Sounds good at first, but what does it really do? Does it produce the Something or consumer the Something or maybe refine the Something? Engine is a word overused to the point of being more confusing than useful. Perhaps you need to better define this idea before you just call it an engine.
Adding the word “object” to the name of a coded object adds nothing. You already know it’s an object, so adding it is meaningless and just adds extra keystrokes every time you want to use that object. Sometimes you may use more vague names for an abstract class or parent class, but in general more specific is better. The same with methods. Avoid the overly generic “HandleOutput”. That tells me you’re not sure what this is supposed to do.
Another example of wasted characters is putting the type of object in the name, when it’s already understood from context. Like with spring or blueprint xml definitions. You know these are blueprint definitions because of their location, context, and content, so to have the name “blueprint-cnf.xml” is meaningless once you move beyond the “Hello World!” tutorial. This name shows up in monitoring & admin tools and you will have 20-30 camel contexts all named the same thing for the first 10-15 characters. It’s like trying to find the plumber in a room full of guys with name tags that all say “Member”.
Also adding a number to an object or method doesn’t tell you anything other than it’s different. You have to read the code to see how it’s different. Using a method signature such as open(Node node) vs open(String xml) is explicit and useful. But open1() vs open2() is meaningless.
Using Common Pattern or Paradigm Names Differently
Using the words “view” and “model” and “controller” in a context that is not the MVC paradigm can create confusion. Or using any of the common Design Pattern names (singleton, decorator, observer, etc.) in a way inconsistent with the commonly understood pattern is also a way to confuse and mislead fellow technologists. Another good place to look at naming is in Enterprise Integration Pattern names. Using familiar names in an unusual or just different way leads to confusion.
A good idea would be to read through these paradigms and their naming. Using these patterns is also an excellent choice for design implementations in addition to naming. You would be wise to adopt these patterns and use the names for them consistently.
Naming Sins to Avoid
- SomethingManager suffix
- SomethingObject suffix
- TheSomething prefix
- ASomething prefix
- Misusing a common pattern name
- profanity anywhere
Method/Function Naming verbNoun pattern
A good pattern to follow for naming a function or object method is verbNoun, such as getNode(), or findNodes(), transformMember(), isDirty(). These use the verbNoun pattern and some also reference what they return such as a node, a set of nodes, or transformed member. In the case of a boolean, specifying the condition being tested with “is” helps make it clear what true/false means. Instead of being confused about cleaned() = true, does true mean it’s been cleaned or does true mean it should be cleaned?
Giving your classes and objects good, descriptive names isn’t easy. Steve McConnell provides a few helpful guidelines for routine naming in Code Complete:
- Describe everything the routine does – And we mean literally everything. If that makes the name ridiculously long, the name isn’t the problem. Your routine is.
- Avoid meaningless, vague, or wishy-washy verbs – Like UrlManager, or HandleOutput(), or PerformServices(). Be specific. What does it do? If you can’t answer that question succinctly, it may be time to refactor the code until you can.
- Don’t differentiate routine names solely by number – I include this only for completeness. If you ever find yourself writing OutputUser1()and OutputUser2(), God help you. And God help the team you work with.
- Make names as long as necessary – According to McConnell, the optimum name length for a variable is 9 to 15 characters; routines tend to be more complex and therefore deserve longer names. Make your names as long as they need to be in order to make them understandable.
- For functions, try using a description of the return value – An easy, straightforward rule. Some examples are printer.IsReady(), pen.CurrentColor(), etcetera.
- Use opposites precisely – For every Open(), there should be a Close(); for every Insert(), a Delete(); for every Start(), a Stop().
- Establish conventions for common operations – This is best illustrated with an example, and McConnell provides an excellent one:
Now how do I get an Id again?
If you have never been to Jeff Atwood’s site you should be sure to read his wisdom. On naming things Jeff Atwood at CodingHorror.com has this to say:
I’d say renaming classes and variables is one of my most frequent refactoring activities. Creating good names is hard, but it should be hard, because a great name captures essential meaning in just one or two words
It’s difficult to tell what something should be named until you’re completely finished writing it. And like most code, it’s never quite done, so the name may change over time. Succinct, descriptive variable, object, and function names can make the difference between Daily WTF code and… well, code you’d actually want to work on.
Putting in the time to name things or rename things correctly demonstrates professionalism and maturity in software development. This is one of the qualities that separates the coding hack from the professional developer. It’s about craftsmanship and pride in a job well done.