views:

751

answers:

12

A long time ago I have read an article (I believe a blog entry) which put me on the "right" track on naming objects: Be very very scrupulous about naming things in your program.

For example if my application was (as a typical business app) handling users, companies and addresses I'd have a User, a Company and an Address domain class - and probably somewhere a UserManager, a CompanyManager and an AddressManager would pop up that handles those things.

So can you tell what those UserManager, CompanyManager and AddressManager do? No, because Manager is a very very generic term that fits to anything you can do with your domain objects.

The article I read recommended using very specific names. If it was a C++ application and the UserManager's job was allocating and freeing users from the Heap it would not manage the users but to guard their birth and death. Hmm, maybe we could call this a UserSheperd.

Or maybe the UserManager's job is to examine each User object's data and sign the data cryptographically. Then we'd have a UserRecordsClerk.

Now that this idea stuck with me I try to apply it. And find this simple idea amazingly hard.

I can describe what the classes do and (as long as I don't slip into quick & dirty coding) the classes I write do exactly one thing. What I miss to go from that description to the names is a kind of catalogue of names, a vocabulary that maps the concepts to names.

Ultimately I'd like to have something like a pattern catalogue in my mind (frequently design patterns easily provide the object names, for example with a factory)

  • Factory - Creates other objects (naming taken from the design pattern)
  • Shepherd - A shepherd handles the lifetime of objects their creation and shutdown
  • Synchronizer - Copies data between two or more objects (or object hierarchies)
  • Nanny - Helps objects reach "usable" state after creation - for example by wiring to other objects

  • etc etc.

So, how do you handle that issue? Do you have a fixed vocabulary, do you invent new names on the fly or do you consider naming things in the way as I describe as not-so-important or wrong?

P.S.: I'm also interested in links to articles and blogs discussing that issue. As a start here is the original article that got me thinking about it: Naming Java Classes without a 'Manager'


Update: Summary of answers

Here's a little summary of what I learned from this question in the meantime.

  • Try not to create new methaphors (Nanny)
  • Have a look at what other frameworks do

Further articles/books on this topic:

And a current list of name prefixes/suffices I collected (subjectivly!) from the answers:

  • Coordinator
  • Builder
  • Writer
  • Reader
  • Handler
  • Container
  • Protocol
  • Target
  • Converter
  • Controller
  • View
  • Factory
  • Entity
  • Bucket

And a good tip on the road:

Don't get naming paralysis. Yes, names are very important but they're not important enough to waste huge amounts of time on. If you can't think up a good name in 10 minutes, move on.

+4  A: 

Being au fait with patterns as defined by (say) the GOF book, and naming objects after these gets me a long way in naming classes, organising them and communicating intent. Most people will understand this nomenclature (or at least a major part of it).

Brian Agnew
Fowler is a good reference for me but the GOF is a great recommendation.
Lazarus
Forgive my ignorance. Which Fowler book are you referring to ?
Brian Agnew
http://www.amazon.com/Patterns-Enterprise-Application-Architecture-Martin/dp/0321127420
Jim Ferrans
My bad, meant to put the link in! Doh!
Lazarus
Hmm, sometimes this works (for example like a Factory or a Strategy) but in other times I feel that this does communicate the way of implementation (I used a pattern!) more than the intent and job of the class. For example a Singleton's most important thing it what it represents - and not that it is a Singleton. So strict naming after the patterns used feels like strict naming after the types used. For example Hungarian notation as mis-applied by the Windows Systems group (describing the C data type instead of "intent type")
froh42
@froh42 - that's a good point re. exposing implementation. Some care certainly needs to be taken.
Brian Agnew
For technical infrastructure classes, it's usually desirable to make the implementation transparent - and most of the canonical design pattern names communicate both implementation and intent. Domain model classes are another matter, though.
Jeff Sternal
+1  A: 

I believe the critical thing here is to be consistent within the sphere of your code's visibility, i.e. as long as everyone who needs to look at/work on your code understands your naming convention then that should be fine, even if you decide to call them 'CompanyThingamabob' and 'UserDoohickey'. The first stop, if you work for a company, is to see if there is a company convention for naming. If there isn't or you don't work for a company then create your own using terms that make sense to you, pass it around a few trusted colleagues/friends who at least code casually, and incorporate any feedback that makes sense.

Applying someone else's convention, even when it's widely accepted, if it doesn't leap off the page at you is a bit of a mistake in my book. First and foremost I need to understand my code without reference to other documentation but at the same time it needs to be generic enough that it's no incomprehensible to someone else in the same field in the same industry.

Lazarus
Still, a consistent if slightly unintuitive convention is better than just starting your own convention. People working on a project will learn any consistent convention very fast and soon forget that the functionality isn't quite what might be expected on first glance.
John
@John, that's exactly what I said. The convention needs to be accepted by the group and if you are working in a company then see if there is a company convention. For company I'm thinking of any group, be it an open source project team or a loose collection of programmers. If everyone just took what was available that almost fit their requirements then I think we'd be sorely lacking in innovation.
Lazarus
A: 

I'd consider the patterns you are using for your system, the naming conventions / cataloguing / grouping of classes of tends to be defined by the pattern used. Personally, I stick to these naming conventions as they are the most likely way for another person to be able to pick up my code and run with it.

For example UserRecordsClerk might be better explained as extending a generic RecordsClerk interface that both UserRecordsClerk and CompanyRecordsClerk implement and then specialise on, meaning one can look at the methods in the interface to see what the its subclasses do / are generally for.

See a book such as Design Patterns for info, it's an excellent book and might help you clear up where you're aiming to be with your code - if you aren't already using it! ;o)

I reckon so long as your pattern is well chosen and used as far as is appropriate, then pretty uninventive straightforward class names should suffice!

CJ
I have commented on that on Brian Agnew's answer. I don't feel the pattern names make good class names only in some cases (Factory, Strategy) but not in others (Singleton). I want the names to reflect the job of the class not the way how I implemented it.
froh42
A: 

Specific to C#, I found "Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries" to have lots of good information on the logic of naming.

As far as finding those more specific words though, I often use a thesaurus and jump through related words to try and find a good one. I try not to spend to much time with it though, as I progress through development I come up with better names, or sometimes realize that SuchAndSuchManager should really be broken up into multiple classes, and then the name of that deprecated class becomes a non-issue.

AaronLS
+3  A: 

I think the most important thing to keep in mind is: is the name descriptive enough? Can you tell by looking at the name what the Class is supposed to do? Using words like "Manager", "Service" or "Handler" in your class names can be considered too generic, but since a lot of programmers use them it also helps understanding what the class is for.

I myself have been using the facade-pattern a lot (at least, I think that's what it is called). I could have a User class that describes just one user, and a Users class that keeps track of my "collection of users". I don't call the class a UserManager because I don't like managers in real-life and I don't want to be reminded of them :) Simply using the plural form helps me understand what the class does.

Droozle
+4  A: 

Sounds like a slippery slope to something that'd be posted on thedailywtf.com... "ManagerOfPeopleWhoHaveMortgages" etc

I suppose it's right that one monolithic Manager class is not good design, but using 'Manager' is not bad. Instead of UserManager we might break it down to UserAccountManager, UserProfileManager, UserSecuritymaanger, etc. 'Maanger' is a good word because it clearly shows a class is not representing a real-world 'thing'. 'AccountsClerk' - how am I supposed to tell if that's a class which manages user data, or represents someone who is an Accounts Clerk for their job?

John
A: 

I'm all for good names, and I often write about the importance of taking great care when choosing names for things. For this very same reason, I am wary of metaphors when naming things. In the original question, "factory" and "synchronizer" look like good names for what they seem to mean. However, "shepherd" and "nanny" are not, because they are based on metaphors. A class in your code can't be literally a nanny; you call it a nanny because it looks after some other things very much like a real-life nanny looks after babies or kids. That's OK in informal speech, but not OK (in my opinion) for naming classes in code that will have to be maintained by who knows whom who knows when.

Why? Because metaphors are culture dependent and often individual dependent as well. To you, naming a class "nanny" can be very clear, but maybe it's not that clear to somebody else. We shouldn't rely on that, unless you're writing code that is only for personal use.

In any case, convention can make or break a metaphor. The use of "factory" itself is based on a metaphor, but one that has been around for quite a while and is currently fairly well known in the programming world, so I would say it's safe to use. However, "nanny" and "shepherd" are unacceptable.

CesarGon
+1 for avoiding metaphors that could be difficult to understand for someone else
rossoft
+4  A: 

I asked a similar question but where possible I try to copy the names already in the .NET framework, look for ideas in the Java and Android frameworks.

Seems Helper, Manager, Util is the unavoidable noun you attach for coordinating classes that contain no state and are generally procedural and static. An alternative is Coordinator.

You could get particularly purple prosey with the names and go for things like Minder, Overseer,Supervisor,Administrator,Master but as I said I prefer keeping it like the framework names you're use to.

Some other common suffixes (if that is the correct term) you also find in the .NET framework are

  • Builder
  • Writer
  • Reader
  • Handler
  • Container
Chris S
I like these a lot. They do not fall into the trap of bad or unknown metaphors because they are already in use by the .NET Framework. It might be interesting to look at other libraries (Java), too for more input of what is commonly used.
froh42
A: 

We could do without any xxxFactory, xxxManager or xxxRepository classes if we modeled the real world correctly:

Universe.Instance.Galaxies["Milky Way"].SolarSystems["Sol"]
        .Planets["Earth"].Inhabitants.OfType<Human>().WorkingFor["Initech, USA"]
        .OfType<User>().CreateNew("John Doe");

;-)

herzmeister der welten
How would you get to parallel universes and alternate dimensions?
tster
That's easy: Omniverse.Instance.Dimensions["Ours"].Universes["Ours"].Galaxies... ... okay okay I admit this would require a recompilation. ;-)
herzmeister der welten
+1  A: 

When I find myself thinking about using Manager or Helper in a class name, I consider it a code smell that means I haven't found the right abstraction yet and/or I'm violating the single responsibility principle, so refactoring and putting more effort into design often makes naming much easier.

But even well-designed classes don't (always) name themselves, and your choices partly depend on whether you're creating business model classes or technical infrastructure classes.

Business model classes can be hard, because they're different for every domain. There are some terms I use a lot, like Policy for strategy classes within a domain (e.g., LateRentalPolicy), but these usually flow from trying to create a "ubiquitous language" that you can share with business users, designing and naming classes so they model real-world ideas, objects, actions, and events.

Technical infrastructure classes are a bit easier, because they describe domains we know really well. I prefer to incorporate design pattern names into the class names, like InsertUserCommand, CustomerRepository, or SapAdapter. I understand the concern about communicating implementation instead of intent, but design patterns marry these two aspects of class design - at least when you're dealing with infrastructure, where you want the implementation design to be transparent even while you're hiding the details.

Jeff Sternal
+1  A: 

Since you're interested in articles in this area, you might be interested in Steve Yegge's opinion article "Execution in the Kingdom of Nouns":

http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html

stusmith
This is truly a brilliant rant!
froh42