24

An awkward, open question, but it's a problem I'm always bumping against:

Software that's easy to maintain and work with is software designed well. Trying to make a design intuitive means naming your components in such a way that the next developer should be able to infer the function of the component. This is why we don't name our classes "Type1", "Type2", etc.

When you're modelling a real-world concept (e.g. customer) this is generally as simple as naming your type after the real-world concept being modelled. But when you're building abstract things, which are more system-oriented, it's very easy to run out of names which are both easy to read and simple to digest.

It gets worse (for me) when trying to name families of types, with a base-type or interface which describes what the components have to do, but not how they work. This naturally leads to each derived type trying to describe the flavour of the implementation (e.g. IDataConnection and SqlConnection in the .NET Framework), but how do you express something complicated like "works by reflection and looking for a specific set of attributes"?

Then, when you've finally picked a name for the type you think describes what it's trying to do, your colleague asks "WTF does this DomainSecurityMetadataProvider actually do?"

Are there any good techniques for choosing a well-meaning name for a component, or how to build a family of components without getting muddled names?

Are there any simple tests that I can apply to a name to get a better feel for whether the name is "good", and should be more intuitive to others?

8
  • 20
    there are six techniques that were proven to work for me: 1) spend a lot of time on inventing names 2) use code reviews 3) don't hesitate to rename 4) spend a lot of time on inventing names 5) use code reviews 6) don't hesitate to rename
    – gnat
    Jan 13, 2012 at 13:36
  • 5
    @gnat: Please post your answer as an answer so we can up vote it.
    – S.Lott
    Jan 13, 2012 at 13:43
  • 2
  • 3
    I often use a thesaurus when doing new development to help me come up with good names. Jan 13, 2012 at 14:29
  • 3
    I try to avoid calling anything "Manager". Alan Green and Jeff Atwood argue that the term is overused and is too vague to convey meaning. I have to agree. Jan 13, 2012 at 15:56

8 Answers 8

41

For naming, there are six techniques that were proven to work for me:

  1. spend a lot of time on inventing names
  2. use code reviews
  3. don't hesitate to rename
  4. spend a lot of time on inventing names
  5. use code reviews
  6. don't hesitate to rename

PS. In case if your API is going to be public, above applies before that - because, you know,

"Public APIs, like diamonds, are forever. You have one chance to get it right so give it your best..." (Joshua Bloch, How to Design a Good API and Why it Matters)

8
  • 1
    In case it's a public API, there are three additional techniques you can use...
    – UncleZeiv
    Jan 13, 2012 at 14:35
  • 1
    @UncleZeiv: such as....? Jan 13, 2012 at 14:43
  • 3
    @FrustratedWithFormsDesigner: 1. spend a lot of time on inventing names 2. use code reviews and 3. don't hesitate to rename
    – S.Lott
    Jan 13, 2012 at 15:02
  • 3
    This answer has convinced me that generally: no, there is no easy way to get names right. Only trying really hard works. Jan 13, 2012 at 16:16
  • 4
    7. Don't hesitate to redesign types or functions if it turns out that it's impossible to devise a proper name for them. Well-designed code can always be properly named.
    – Joren
    Jan 14, 2012 at 0:16
8

My base test is if you can describe the variable's function using only words from the variable:

e.g. if DomainSecurityMetadataProvider either "Provides Domain Security Metadata" or "Provides Metadata relating to Domain Security", it's good.

However, there are nuances that vary from person to person:

e.g. For me, original_team_code is the code for the original team, whereas for someone else it might be the original code for the team. My personal favourite one of these was "UnsafeLegacyMutex", which I couldn't help but read as "This is a Legacy Mutex which is Unsafe", rather than "This is a Mutex for ThreadUnsafe Legacy Code".

So my extended test is to write the variable down on a board/wiki/chat, and have people guess what it means.

7

Are there any good techniques for choosing a well-meaning name for a component, or how to build a family of components without getting muddled names?

Not really.

One tip, however, is to avoid "passive voice".

"DomainSecurityMetadataProvider" is passive. There's no verb, it's all nouns and nouns used as adjectives.

"ProvideMetadataForDomainSecurity" is more active. There's a verb.

Object-oriented programming is all (really) noun-verb. Noun == object. Verb == method. So a class name is generally very "nounish". To break this habit, and start inserting verbs, is difficult.

Are there any simple tests that I can apply to a name to get a better feel for whether the name is "good", and should be more intuitive to others?

Yes. You defined an excellent test in your question. Ask other people.

In the olden days we called this a "design walkthrough". It was a big, sweaty deal in a waterfall methodology. Nowadays, with Agile methods, it should be an ordinary collaboration between the author and users of a class. It doesn't (and shouldn't) take long. Discussing the design (and the names) before writing the tests (and the code) will reduce the astonishment factor and can prevent WTF's.

5
  • 12
    Not sure I agree with the passive voice idea. To me, Classes make more sense as Nouns.
    – deworde
    Jan 13, 2012 at 13:53
  • 8
    Generally speaking, I'm trying to keep my type names in passive voice, as it suits the noun-verb style of OOP. I would consider ProvideMetadataForDomainSecurity to be a poor type name. Method names are typically much easier to name precisely because I'm free to use use verbs. The restriction on language is the crux of the problem. Jan 13, 2012 at 13:57
  • As much as I like "ask people" as a real test, I must ask my colleagues about naming at least twice a day. I'm hoping for something that doesn't require other people's time. Jan 13, 2012 at 13:59
  • 2
    Classes do make sense as nouns. The issue is these complex classes with long noun-adjective phrases. Prepositions may help, too.
    – S.Lott
    Jan 13, 2012 at 13:59
  • 2
    Collaboration is the secret of good software. Collaboration takes time. There's no royal road to good writing.
    – S.Lott
    Jan 13, 2012 at 14:00
6

Using a thesaurus

Very often I will refer to a thesaurus when doing new development in order to find appropriate words to describe my classes and methods.

Classes that primarily contain operation logic

I tend to name classes that primarily provide operation methods in a noun-verb structure such as "EntityProvider", "EntityLocator", etc.

These classes generally don't contain a lot of state.

Classes that contain state

UI screens and data entities are generally stateful, and so I simply name these classes with a noun or adjective-noun pattern.

Examples: Person, Employee, CurrentEmployee, FormerEmployee

Utility classes

Classes that only contain static methods are generally considered "utility" classes, so I consistently name them with a "Utility" suffix.

Examples: NetworkUtilities, FileUtilities

Tests

I don't have any good tests for deciding whether something is poorly named, but I would suggest to try to use a single noun and/or a single verb in the name, then think about whether that noun/verb accurately describes what you're naming.

If you feel that there is more to the class/method that is not captured by the name, then that class/method might need to be refactored.

Alan Green and Jeff Attwood have written about the evils of naming classes with the "Manager" suffix. They argue that the term "Manager" is overused and is too vague to convey anything meaningful. I have to agree.

Jeff's article also provides a list of suggested guidelines from Steve McConnell's Code Complete.

variables

Recently I've been experimenting with longer descriptive variable/parameter names that incorporate prepositions, such as "Of", "By", "For", etc. Some examples are shown below:

string firstNameOfEmployee;

string lastNameOfEmployee;

// here I nimbly avoid worrying about whether to call it "Id" or "ID" :)
int idOfEmployee;

decimal amountForDeposit;

Account accountForDeposit;

I find that this works fine with Visual Studio's intellisense feature making it easy to type these long names. I also find that there is less duplication of variable name prefixes (e.g. personID, personFirstName, personLastName vs. idOfPerson, firstNameOfPerson, lastNameOfPerson), providing a better "hash" that makes intellisense even more useful.

3
  • 1
    I'll second the point about long variable names, again, Visual Studio (if you're using it) makes this a no-brainer. It is a lot less harmful to have long variable names that are explicit than short variable names where you have to "think" about or investigate what the name actually means. Also think about context. I'd rather see "peopleToDelete" than "listOfPeople". Again, Visual Studio tells you the type of the variable, no need to include it.
    – John B
    Jan 17, 2012 at 19:13
  • I also dislike the elaborate Hungarian notation you've added to variable names. I shouldn't need to care if a collection of person IDs is a List, array, IEnumerable or ConcurrentQueue. It's a bunch of IDs I need to enumerate over, and the implementation detail of how they're stored is unnecessary mental baggage. Though I do generally agree that if a longer name is considerably more descriptive, it should be favored over a shorter, less clear name. Jan 19, 2012 at 20:17
  • @Allon - Funny, I was about to revise my answer based on SkippyFire's comment. I actually agree with you; my example smacks of Hungarian notation. My only defense is that it's easy to read the code and understand the datatypes involved without an IDE available, such as if I'm reading through a source-control diff. That's no excuse, though. :) I'm going to revise my example to be along the lines of firstNameOfEmployee, lastNameOfEmployee, etc. Jan 19, 2012 at 20:23
2

Then, when you've finally picked a name for the type you think describes what it's trying to do, your colleague asks "WTF does this DomainSecurityMetadataProvider actually do?"

What kind of name do you expect for a complex and domain specific class? This is about as good as it's going to get without making your class name a sentence (which will have everyone thinking you've given too much responsibility to a single class)

I would consider dropping provider from the name. If it specifically mentions Metadata, everyone already knows you're using reflection. You could make it one word more concise (or possibly change to another word--it's more of a consumer than a provider from what you've written)

2
  • The metadata in question is not derived from reflection (but it does describe how to treat types). The type implements an ISecurityMetadataProvider interface, which exists an an injectable point in the security infrastructure, to provide information to the subsystem. Naming is hard. Jan 13, 2012 at 14:30
  • I consider DomainSecurityMetadataProvider to be a provider of DomainSecurityMetadata object, where DomainSecurityMetadata is metadata itself. Clear and understandable name. I don't even need to know what DomainSecurityMetadata is! It is just some object, which this provider provides. Just removing a Provider suffix doesn't improve readability, but quite the contrary - reduce it. Without this suffix I'd think that it is just some metadata (container object for some metadata), but not an object to get metadata from (a provider). Feb 25, 2018 at 17:40
0

Use metaphors to describe parts of the system. Not only it will make you discover new analogies, it will help naming easier.

(I am aware this is not a strong example but anyway) For example you can call a variable or a type as mailbox, which serves as a queue for the received messages for a class.

-1

One thing I'd be very firm on is that Names should NEVER be allowed to be incorrect. Best example, during some re-factoring, a lot of code changed, and a few variables started referring to something other than what their names suggested.

Pretty soon, one programmer was spending ages and using some very expensive database calls trying to get hold of certain pieces of data which had been extracted and stored already. I renamed everything and suddenly we could remove a ton of overcomplicated and buggy logic.

2
  • 1
    you should delete this answer and edit into your origination answer
    – Ryathal
    Jan 13, 2012 at 14:17
  • I think this is a different answer to my other answer.
    – deworde
    Jan 13, 2012 at 14:57
-1

Hopefully cases where you have to think so hard about the names are rare. When those cases arise, just write a paragraph explaining what the class does. Contrary to in-function comments or function level comment, the primary purpose of a class rarely changes so the risk of comments getting out of date is relatively small. So you have the luxury of writing a couple of paragraphs or even draw ASCII to explain what the class does.

Not the answer you're looking for? Browse other questions tagged or ask your own question.