System Of Names

The following pattern was written by WardCunningham as an exercise at the first HillsideGroup meeting in August 1993. It expands on the useful tip: use a thesaurus to name objects. The form mimics that of ChristopherAlexander and, as such, includes references to prerequisite and subsequent patterns. They were and remain hypothetical as they were beyond the scope of the writing exercise.


. . . ObjectsFromTheUsersWorld and their computational helpers, EnginesAndHolders?, PolicyAndMechanism and CentralTransaction? all have their WorkingNames. This has allowed us to perform a WorkspaceTest* and make the PilotPackage?. Further, class transforming patterns like InstantiatedMethod? and DelegateResponsibility adjust and elaborate this model until it becomes a set of collaborating objects with well distributed responsibilities. However, the names of these objects may no longer make manifest the responsibilities they carry. Be warned:

* This is simply a test run in a Smalltalk workspace. The code has to be correct for this to work, but it's not necessary for the identifiers to be aligned into a system of names.

People often make assumptions based on the object names alone.

The brainstorming of names and other object identification procedures cannot anticipate their actual interplay in a running program. Further, many terms are borrowed from related domains with subtle meanings lost in the process. Confusion about these subtleties will weaken communication among developers resulting in continuous clarifications. The case is even worse with the eventual reader who has no simple access to such clarification. Collaborations involving many objects may even encounter clashes of metaphors which are at best humorous and at worst debilitating.

Therefore:

Revise the names of your objects to reflect their ultimate roles.

Words drawn from human relations often imply much secondary meaning. Make sure these align with the intent of your responsibility allocations.
		Master
  compare:	|	with:  Originate -- Answer
		Slave
Avoid names that have confused or unfortunate meanings in related domains. Remember, your reader will assume you drew the names from somewhere. Consult a Thesaurus and try the synonyms it suggests as you might use it as a class name. Consult your colleagues as you do this. What do they think it means as a class name? Find words consistent with a metaphor that suggests the actual behavior of your program.

Your new names will lead you to an even deeper understanding of your objects. If required, consider FactoredResponsibilities? and NuggetsOfExperience? at this time. Also, the metaphor implied by your names will suggest other improvements like NegotiationProtocols? and ActiveMethodCategories? . . .


The pattern encourages you to make the SystemMetaphor manifest in your names, once you found it, rather than to make your names systematic as in HungarianNotation. -- WardCunningham

You can take a look at http://www.objectmentor.com/publications/naming.htm for some naming rules that might be helpful. Generally, I prefer the 'purpose' style naming over the 'literal' naming of things (for instance "windshield", rather than "front glass"). The other preferences I have are pretty much in the Document. -- TimOttinger

Choosing relevant names is important. The StroopEffect? described in The PragmaticProgrammer illustrates how easily we can be misled by inappropriate names: http://www.pragmaticprogrammer.com/ppbook/stroop.html


Sometimes people will use words that seem obvious, but can create confusion. My pet hate is:

  aNumber.add(7);

Does this modify the value of aNumber? If I compare it to

  aList.add(anItem);

Then I expect both methods to modify their objects. However, I often find some people will assume that the first example will not modify aNumber. For that functionality I would prefer to see a different word, for example

  aNumber.plus(7);

Even better is to have a language where operators are not methods on objects; but some people would say that that's not pure OO (whatever that is). Java's Math object is an example of this. Unfortunately, its a very bad example because it only uses primitive types and I can't specialize its operators for my own classes. SDL's ADTs are a better example! --DaveWhipp

(Complaint about Java's choice of + for concatenation retracted.)

I think the issue is the difference between an operation on a class and an operation involving a class. If you have an operation on a class, you change the internals of the class and "aNumber.plus(7)" would be correct. If you have an operation involving a class, you do not change the internals of the class and the method should not be a member of the class, i.e. something like "Add(aNumber, 7)". -- WayneMack

Another example is found in the TestResult class of the xUnit frameworks. It has a method named runTests, and a number of query methods such as testFailures and testErrors. My intuition told me that runTests probably runs the tests. No such luck: it's a query, too.

I can think of any number of better names for all three methods. "numberOfXxx" or "xxxCount" would be less confusing. The word "test" is not necessarily needed, because its in the class name. For example: TestResult::numberOfErrors or TestResult::errorCount; TestResult::numberOfTests or TestResult::testsRunCount. In violation of Demeter, we could even try errors().size() -- errors() returns a container of the test failures. (Oh yes, in CppUnit they should be declared as const methods). --DaveWhipp

LanguageOrientedProgramming and the ThelopLanguage try to help with such problems. LOP commands that programmers should use words with consistent meaning. THELOP implements a vocabulary and rules. I don't know the TestResult class you are talking about, but I would suggest names like
	TestResult::GetRunCount
	TestResult::GetErrCount
	TestResult::GetFailureCount
or (better)
	TestResult::RetRunCount
	TestResult::RetErrCount
	TestResult::RetFailureCount
-- HelmutLeitner


or (better)
	TestResult::RetRunCount
	TestResult::RetErrCount
	TestResult::RetFailureCount

Personally, I find these pretty nasty. I mean, why avoid typing three more letters to complete return or two more to complete error? There is a pretty well accepted get/set conventioned that has been used in programming for years. Why is using Ret or even Return better? What extra information does it provide? -- RobertDiFalco

Ret is a word in the ThelopLanguage (abbreviated from return). It tells us that the result is passed by the function return value. Get is in common use, but not consistently. Get in THELOP means that the result is passed by an output parameter. If you follow the principles of LanguageOrientedProgramming, you may chose other words (and create your own LopLanguage) but you have to be consistent.-- HelmutLeitner


So, when you decide to use a naming scheme like the ones popular since SmallTalk, might that mean that you created to many objects ?

I really find the pattern of making every variable that has some behaviour into a new class disturbing.

Nested namespaces don't help a lot when the hierarchy is so big that you don't know all objects by name, so you use naming systems.

Amen. -- HelmutLeitner


I'm not sure I follow this. The SystemOfNames is a metaphorical system to help understand the system and keep its ConceptualIntegrity. Naming systems, such as HungarianNotation are a different thing.

A naming scheme should be consistent at the level of abstraction it is applied. If its top level business then offices, managers, clients etc. If its Db access then row, resultSet, table etc. Naming schemes tend to fall apart when you mix abstractions in the name, that was the big problem with HungarianNotation for me.

I haven't found name clashes to be much of a problem in Smalltalk (though I only play with it).

I'm not sure about making every variable that has behaviour into a new class. Why would you do that? If its a string use the string class. If it is has behaviour very like a string and it is used all over the place then a new class seems reasonable (or extend string!). --TomAyerst
See also: http://www.construx.com/chk08.htm

: Are loop index names meaningful (something other than i, j, or k if the loop is more than one or two lines long or the loop is nested)?

This suggestions in this link are just plain wrong. Variables generally should have short, generic names. Classes should have descriptive names. One of my pet peeves is long loop variables like 'Iterator iteratorOverSomethingOrAnother;'. Just call it 'i', 'j' or 'k'. I read code by looking at the objects, not at the variables. --TimBurns

I think there should be an inbetween. When you just have variables like 'i'... it's hard to remember what they are. I don't think your need 5 or 6 word variables though. - Jessica

With you there. Loop variables are only dangerous when they are used outside of the loop.

FWIW, I always use a single word as my iterator variable name - and use the name to indicate something about the purpose of the loop. Index for when I'm processing things, Scan for when I'm looking for something, etc. - BevanArps

When you just have variables like 'i'... it's hard to remember what they are.

In an informal survey of 11 nearby programmers, all were able to identify 'i' as a loop counter or array index. I think the brevity of 'i' is more readable than 'index'. If loop variables have special meaning such that remembering what they are is valuable, then use an appropriate, descriptive name.

--ChrisFay

loop counter or array index

Often it is useful to distinguish between a counter and an index (i short for integer gets used for both) Using this discipline has been helpful in avoiding OffByOne errors, which can occur when confusing counting (mostly one-based), with indexing (often 0-based). Also layerIndex, frameIndex, pixelIndex can be a lot more helpful than i, j, and k. see ZeroAndOneBasedIndexes

Perhaps the original author was suggesting that when you have all your variables like 'i'...

I have developed the habit of using 'ii', 'jj', 'kk' for (eg) loop-variables, for ease of search/replace operations, and for other benefits. - jgsack

What are these "other benefits"? I do the same with my loop-variables, but I've only been able justify using doubled names with the search/replace argument (which doesn't work so well in Perl or PHP, as $i is reasonably easy to find already). -- rhoward
Michael H. Brackett develops the concept of formal data names in considerable detail in his books. According to Brackett, all items of data should have names that are as formal as the names for chemical compounds and plants. One component of a formal data naming scheme is the data naming taxonomy. Brackett proposes the following:
	  Data Site:
	  [Data Occurrence Selection]
	  "Data Occurrence Role"
	  Data Subject.
	  Data Subject Hierarchy Aggregation^
	  Data Code Set;
	  Data Characteristic,
	  Data Characteristic Variation-
	  (Data Characteristic Substitution)
	  'Data Code Value'
	  <Data Version>
	  Data Rule!
For example, a person's first name in the HR database might be formally named:
	  HR: Person. Person Name Individual
Their height in meters might be:
	  HR: Person. Person Height, meters-
For more information, check out his books or his web page at
  http://members.aol.com/mhbrackett
For the moment, there also happens to be a chapter of his book 'The Data Warehouse Challenge' available on line that covers formal data names in detail. The URL is: http://www.ee.iitb.ernet.in/tilak/~zainul/work/books/0471127442/ch05/069-071.html
Moved from VagueIdentifierNames?

Abstractions should be precise. Likewise, their names need to be precise.

Sometimes developers confuse abstraction (a precise thing) with overgeneralization (which is sloppy). One way that this shows up is in vague identifier names, and collections of similar names.

"Data", "Object", "Class" are words that shouldn't appear in identifier names. Identifiers should never be differentiated by a single character wart. If two class names are accidentally used interchangeably by their author, they are too imprecise.

I've just been fighting VisualBasic and the identifier "DataObject?". 2 strikes! --PaulHudson

Another common problem in MicrosoftWorld? is when applications use ADO Recordsets, and pass these around as arguments called Recordset. Obviously, these should be named by the type of record that they store: Sub SortClients?(Clients As ADODB.Recordset) As ADODB.Recordset

An obvious exception to these rules is when the problem domain is expressed in these terms. For example, a DungeonsAndDragons game would have "CharacterClass?", and so on. -- AlastairBridgewater

I think another exception to these rules is in naming method arguments. I generally design classes using LiskovWingSubtyping. There are therefore times when I form an argument name by appending the name of the most abstract class that may be passed to it. A typical example might be anObjectCollection versus anObjectDictionary. Also, I use similar suffixes to queue a reader as to the type of argument (a sort of LimitedHungarian?). Examples of this might be aNameSymbol versus aNameString. I therefore think that use of "Object" and "Class" in this context, as the name of real classes, are exceptions to this rule. If a method argument can be any object, I find it perfectly reasonable and even correct to name that argument "anObject" (such as the argument to #= in Smalltalk). Similarly, if a method argument can be any class instance, I find it similarly correct to name such an argument "aClass". --TomStambaugh


How do you name the same thing with a different name? For example, I have a class which contains a Type object and provides some more functionality around it. The most natural name for my class is Type. I am just adding functionality that naturally goes with type. But I can't reuse Type. So what should I call it? --AsimJalis

This suggestions in this link are just plain wrong. Variables generally should have short, generic names.

How can suggestions be 'just plain wrong' when the alternative suggestion is "generally"?

---Michael Bolton


Also see: SameThingSameName


CategoryPattern CategoryNaming CategoryCodingIssues

EditText of this page (last edited July 14, 2008) or FindPage with title or text search