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 Answers8

43

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)

sindhu_sp
  • 105
gnat
  • 20,543
  • 29
  • 115
  • 306
9

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.

deworde
  • 1,932
6

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.

S.Lott
  • 45,522
  • 6
  • 93
  • 155
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.

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)

brian
  • 3,569
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.

nimcap
  • 613
-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.

deworde
  • 1,932
-2

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.

kizzx2
  • 277