There are 2 hard things in
electronic machine code writingcomputer science: naming things and cache invalidation.
We'll talk about the first today: the principle we want to follow is describing the fundamental properties of an object in its name. Electronic machines may be built with hydrauclic technology but be programmed similarly; and we do not write down code anymore in cards and listings, but type it and manipulate it on screen. The study of the fundamental properties of computing machines and algorithms is called in fact computer science.
Nouns and verbs
Let's start with something simple: class names. A class describe a set of objects; there are many problematic names we should avoid.
Overly generic names like Object, Data, but also Element and Item add nothing to the construct and do not help us distinguish between different classes: how are InvoiceElement and InvoiceRow different? Is it one a subset of the other?
The common suggestion to avoid names with a -er or -or suffix tries to avoid the sostantivation of verbs to build fake names. Again, Manager and Handler classes are just generic verbs instead of descriptions; furthermore, even when the verb is precise like in the case of CommandsHolder (that's mine!) or "ER" they point to procedural concepts (an action) translated in OO syntax.
Too technical terms are a plague too: while the pattern citation simplifies discussion, a WidgetFactoryPrototype class contains less meaning with respect to a domain-related name like WidgetFamily. Pattern names and references can go into docblocks instead of names. An extension of technical terms is hungarian notation like AuthenticatorInterface, which can be shortened in Authenticator.
Finally, Uncle Bob points out in his Clean Coders series that unpronounceable names hamper the discussion on the code: Clk is an abbreviation that can almost always be expanded into Clock.
The general perspective is that improving a name simplifies discussion and reasoning about an class/object/method/function. Moreover, often the inability to improve a name points to a concept which doesn't actually exist in the domain or whose responsibility should be placed elsewhere, like a Manager class that steals responsibilities from other objects.
Check out the C2 wiki articles on naming to expand on the subject, with contributions from the programmer's elite.
The power of names goes beyond classes: the REST case is in the realm of architectural styles, a level of abstraction far higher than code.
One of the tenets of REST that is often ignored in mainstream implementations is the hyperlinking of resources (HATEOAS); that is, a REST api should not be explored by arbitrarily appending resource/:id to existing URIs, but by following the links present in the response. Nowadays however, everything not returning SOAP envelopes is called REST incorrectly.
REST proponents are shifting the naming of the technique to take care of this important design choice, renaming REST APIs into Hypermedia APIs. It's difficult to cheat and not including URLs in an Hypermedia API response: how can an hypermedia representation not include links?
The gibberish game
As the initial quote established, this article doesn't try to say that naming is easy. In fact, we should learn more techniques for effective naming.
In Domain-Driven Design, Greg Young suggests a game for deferring naming until a concept is clearly defined and we know enough about it. While designing, you have already been using this technique but probably with real words as placeholders:
- - choose a placeholder (generated, readable word) to describe a concept of the domain, to be modelled in code (e.g. trenty).
- - Discuss with it and even implement the code.
- - Choose a meaningful name to complete the picture, now that you know far more about it than at the start.
J.B. Rainsberger proposes a process for improving names, since get them right at the first time is as difficult as for other design decisions:
- start from foo or other nonsensical names.
- Choose a more accurate name, like getRoute(). Most people stop at this stage.
- Move to a precise name, even if it's much longer: calculateRouteAndStoreIt().
- The precise name points out responsibilities to divide between further methods and objects like calculateRoute(), store() and maybe a RouteFactory class.
Naming is one of the activities that is most often procrastinated or ignored, although it has a large impact on the simplificity and clarity of the code. If naming was a simple operation, we would already did while coding: but embracing the complexity of it has lead us to learn more techniques that we can use, like the Gibberish game and Rainsberger's process for improvement.