Naming Classes - How to avoid calling everything a "<WhatEver>Manager"? [closed]
Asked Answered
M

12

1478

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 guard their birth and death. Hmm, maybe we could call this a UserShepherd.

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, e.g. 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 not-so-important or wrong?

P.S.: I'm also interested in links to articles and blogs discussing the 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 metaphors (Nanny)
  • Have a look at what other frameworks do

Further articles/books on this topic:

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

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

And a good tip for 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.

Mok answered 8/12, 2009 at 12:55 Comment(22)
If you need a 'Nanny' object then that implies its possible to break your classes invariants - better redesign your class imhoSanction
see this topics : https://mcmap.net/q/46189/-class-naming-chaos-closed #38519Hf
Thanks for keeping this updated - but ugh, that last tip is terrible advice! If you can't think of a good name in 10 minutes, there's probably something wrong with your class. (With the standard caveats: 1) perfect is the enemy of good, 2) Shipping is a feature - just remember that you're incurring technical debt.)Pathogenesis
Is it OK to list prefix/suffix names you should avoid? I'm thinking of Processor here, it's ambiguous and could be anything that takes an input and produces an output. Also in similar sense, SubSomething should be avoided too.Nottage
@anton1980 See the first comment, this is why it's not constructive. I'm not reopening it, but feel free to bring it up on Meta Stack Overflow if you want the community view.Goerke
If you can't think up a good name in 10 minutes then ask your colleague for help. Don't just give up.Chor
A few years late to this, but I started going with a "Clerk" suffix. Probably just as "bad" as manager, but Clerks IRL are only able to perform functions according to a strict set of business rules. The "Clerk" indicates to the consumer this object type only has these sort of functions available. If you can't find what you need, the clerk needs to be expanded, or a new clerk created to do the work you need.Othaothe
@JamesM. While this sort of information is useful, wouldn't Programmers.SE be more appropriate?Catbird
good list. a couple more I have used in the past: Driver, Arbitrator, Declaration, Instance.Cobden
If you can't think up a good name in 10 minutes, try explaining it to your colleagues; they might think of a good name (user338195), but trying to explain it will probably help you discover what's wrong with it (Jeff).Grave
I use SomeEngine to replace Manager.Scottyscotus
If you can't think up a good name in 10 minutes, the problem is not that you won't have a good name. The problem is that you will most likely have bad design. In other words, the inability to find a clear name isn't a issue in and of itself - but an indication of design flaws that run deeper than that.Sunk
You would call them Manager classes when they do nothing ;) [pun intended] - I have seen same pattern in case of *Util *Helper - when in doubt people will call it helper and live happily ever after. It is hard to think about right names and most developer would give low importance to it therefore they just pick the easiest route. These are common issues that I try to point out during code reviews.Trematode
Add Parser & Formatter to the list if you willBombe
I like the idea of specific naming, but I don't like the approach to use names of human professions as this distracts from the topicAccumbent
Anybody interested may want to read Execution in the Kingdom of NounsBerserk
I think class names are roughly divided into two groups: 1, classes that process data; 2, classes as result of some process/conversion. I would suffix the first class names with a verb and the second class, a noun. For example, UserDataProcessor, DateFormatter, MonetaryConvertor, UtilityHelper, ApplicationLauncher, ExceptionHandler, URLEncoder, InputValidator, ObjectMapper, PatternChecker for class 1, and ProviderResponse, UserIDNameCompositeKey, ConnectionClient, LocalizedMessage for class 2.Ondrej
But, I also think this is very subjective, like XxxService or Utils are also good names for me (classes processing data but with a noun name). Convention is important; but the most important, readability.Ondrej
A class for a user, then a class to create the user, then another class to manage the user's memory allocation - going down that road, you'll find yourself with a code base containing 3 times the classes you actually need to get the job done, where everything is separated to it's own little thingy class that does exactly one thing because Bob's your uncle. I mean, SOLID is nice but man, don't overdo it!Elder
The guy is right, if you can't think of a name in 10 minutes (I'd make it 1 minute myself) move on. Because you are using TDD (you are, aren't you?) you're going to be re-factoring the code as you go and either the design will evolve and the name will become clear after a refactor, or you will come up with a name as you work.Devout
these are all names for procedural code pretending to be object-oriented. be upfront about your procedures: if your User<Manag|Help|Controll|Process|Handl|>er contains a procedure called create, then extract it into its own command class: CreateUser. you're less likely to hide unrelated concerns in CreateUser than you are in UserManager. your lists of procedures, and their complexity, getting out of hand is a smell that something can be extracted into models that don't need any suffix, you just need to find them. a world without -ers is possible.Planetstruck
@TyCobb that is good advice, I asked that question many years ago and now it becomes clear to me that one cause why it is hard is trying to shoehorn things into a OO design which aren't OO. I am not anti-OO nowadays, but my code has a much higher aspect of functional code - and suddenly I don't need to worry anymore. OO has its place and uses, especially on those cases when the names of the things are easy to find. If I want to put things into classes, then your suggestion is probably one of the best ones to follow.Mok
C
263

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

It seems Helper, Manager, and Util are the unavoidable nouns 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, and Master, but as I said I prefer keeping it like the framework names you're used to.


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

  • Builder
    A type that use some parameters to construct an instance of a special type. Builder is usually a throwaway. It may not even need to allocate a variable.
    If the type needs to repeatedly create objects, please use Factory.
    if the type responsible for create multiple different type objects, please use Factories.
  • Writer
    Write some variable into something.
  • Reader
    Read something as variable.
  • Handler
    Designed to deal with a situation or something.
  • Container
    Can put something into it.
Confrere answered 8/12, 2009 at 12:55 Comment(3)
I would like to suggest Conductor, like the conductor of a musical orchestra. It's surely an important role, depending on the nature of collaborations you need to "conduct" (other objects being very specialized actors that should respond to centralized command and don't worry too much about every other collaborator).Stearoptene
I do not believe the solution to -er classes is to come up with a different name. As I've read in many other posts and I've trying to learn the answer, is that you need to change the architecture, not just the name used.Altagraciaaltaic
It's very easy to overthink the names to use, this is an anti-pattern.Careerism
B
148

You can take a look at source-code-wordle.de, I have analyzed there the most frequently used suffixes of class names of the .NET framework and some other libraries.

The top 20 are:

  • attribute
  • type
  • helper
  • collection
  • converter
  • handler
  • info
  • provider
  • exception
  • service
  • element
  • manager
  • node
  • option
  • factory
  • context
  • item
  • designer
  • base
  • editor
Banana answered 8/12, 2009 at 12:55 Comment(2)
In one particular company long ago, I knew an engineer so fed up with the absurd and growing plethora of suffix rules plaguing the company that he defiantly ended every class with Thingy.Codie
This list of names by itself is not so useful without the context of which suffix should be applied.Hardej
T
78

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.

Tolson answered 8/12, 2009 at 12:55 Comment(3)
This argument really breaks down in that obviously Factory itself is a metaphor. Often metaphors will really clear up what an object might be good at, whereas being vague or generic automatically ensures that the only way to figure out what the code does is by reading it fully! The worst case scenario.Ozoniferous
An inventive choice of verb + "er" is usually going to be clearer for concrete classes than a colorful analogy will. New abstractions, on the other hand -- stuff that's a new concept, a new "kind of thing" rather than just a new "thing" -- often do work well as metaphors (Java's "beans", Haskell's "lenses", GUI "windows", many languages' "promises"). Most codebases won't have any genuine inventions like that, though.Overstrung
Metaphors can be great when the chosen word is frequently used, or used as name for a central entity in your application. We once used "DNA" as suffix for a class of entities that both uniquely identify something and carry some additional meta data. The only reason why the name worked is because nothing else is called "DNA", so everyone always immediately knew what the entity was meant to do. A generic suffix like "ID" could never accomplish that, with ID being used by so many other things. Of course, new developers had no immediate understanding of the term and what it was meant to convey.Callison
P
54

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");

;-)

Phyllisphylloclade answered 8/12, 2009 at 12:55 Comment(11)
How would you get to parallel universes and alternate dimensions?Fusspot
That's easy: Omniverse.Instance.Dimensions["Ours"].Universes["Ours"].Galaxies... ... okay okay I admit this would require a recompilation. ;-)Phyllisphylloclade
Update: this was added in .NET 4.0: Universe.Instance.ToParallel() ;)Erythroblastosis
Breaks demeter's law though!Twophase
Those are Objects and Members, not Class namesEndoenzyme
I chuckled, but I can't help but nag. For one @HarryBerry is spot on. For another, "modeled the real world correctly" and .WorkingFor["Initech, USA"] don't really play together. /*...*/.WorkingFor(Universe./*...*/.Planets["Earth"].Continents["North America"].Countries["USA"].Companies["Initech"])./*...*/ would at least be consistent. And why the choice of container type for named entities? And why the choice of key? What if I call .CreateNew("John Doe"); a second time? Throw an exception? What's the key, then? "John Doe 2"? Whitespaces in keys?Irvingirwin
In addition to Harry Berry: what would be the name of the class that creates the User (to which class does CreateNew belong). Your answer doesn´t scope that at all, making your statement "We could do without any xxxFactory, xxxManager or xxxRepository classes if we modeled the real world correctly:" insufficient. You assume all our code is about pure data, which it often is not. It´s also about different strategies to handle that data - which is what we call the business-layer.Sheathbill
"Breaks demeter's law though!": Also I left out checks for null back then, arguably for brevity. ;) ———— "Those are Objects and Members, not Class names": Planets is a collection/list of objects of a type Planet, I would've thought it was self-explanatory. ;) ——— "And why the choice of key?": That was just for illustration purposes, could also be a Guid.Phyllisphylloclade
"What would be the name of the class that creates the User": Yeah indeed good point, looks I had an extension method in mind back then, but this definitely doesn't look very clean. I guess LINQ was all new and shiny back then and I over-estimated the magic it could do. So following Johannes' proposal I nowadays would just do ....Countries["USA"].Companies["Initech"].Users.Add(new User("John Doe"));. And of course you have one of those magic ORM frameworks that track such changes.Phyllisphylloclade
Problem: In case of universe...user.store(universe...database) the user object has to know how to store itself in every kind of data store. In case of universe...database.store(universe...user) the database object has to know how to store every kind of object. That is why you always need something like managers.Celina
It's not very helpful to reduce all possible cases to an example.Chalone
K
48

It 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, UserSecurityManager, etc.

'Manager' 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?

Kunlun answered 8/12, 2009 at 13:26 Comment(6)
What about UserAccounter, UserProfiler and UserSecurer? If you get rid of Manager, you are forced to come up with the specific definition, which I think is a good thing.Puissance
What about UserAccount, UserProfile, UserSecurity oO?Nausea
I would name it "MortageOwnersManager"Bailar
Sometimes the domain have specific names. Like "MortageHolder" that may be better that "MortageOwner"Afton
Manager is not bad at all, it's worked fine in software engineering for decades.Careerism
Manager is great for many cases, but in more complicated situations it's lacking. What if there are 3 types of "manager" for a certain entity? (and a single, monolithic manager doesn't work). That's when generic names like Manager, Utility, Handler or Helper fail, because nobody knows whether method X is in the MortgageManager or the MortgageHandler or it just might be in the MortgageHelper too.Callison
P
32

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.

Pathogenesis answered 8/12, 2009 at 12:55 Comment(0)
N
12

If I cannot come up with a more concrete name for my class than XyzManager this would be a point for me to reconsider whether this is really functionality that belongs together in a class, i.e. an architectural 'code smell'.

Narcis answered 8/12, 2009 at 12:55 Comment(0)
M
12

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).

Mathia answered 8/12, 2009 at 12:59 Comment(5)
Fowler is a good reference for me but the GOF is a great recommendation.Falcon
amazon.com/Patterns-Enterprise-Application-Architecture-Martin/…Jugular
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")Mok
@Mok - that's a good point re. exposing implementation. Some care certainly needs to be taken.Mathia
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.Pathogenesis
M
9

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.

Munshi answered 8/12, 2009 at 13:18 Comment(2)
The problem with this approach is that becomes really hard to search your code for Users, especially if you pass around the manager object. this.users = new Users() But then invariably somewhere else in your code users will refer to an array of Users.Stroup
As you say Users indeed implies a "collection of users" - a collection of entities which is stateful. But SRP would mean you wouldn't want to bundle user management (functionality and business logic) with user data (state). Not saying you're wrong, just that UserManager is appropriate if the class is responsible for managing users and not just storing their state and basic CRUD.Devout
H
8

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.

Havenot answered 8/12, 2009 at 13:13 Comment(0)
F
4

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.

Falcon answered 8/12, 2009 at 13:2 Comment(2)
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.Kunlun
@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.Falcon
G
2

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!

Golf answered 8/12, 2009 at 13:12 Comment(1)
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.Mok

© 2022 - 2024 — McMap. All rights reserved.