This is a very popular statement among software engineers:
There are only two hard things in Computer Science: cache invalidation and naming things.Phil Karlton
Over the years, many other people built on top of this wisdom. Today, you might hear a slight variation of the original statement:
There are 2 hard problems in computer science: cache invalidation, naming things, and off-by-1 errors.Leon Bambrick
If you are, like me, also interested in the history of computer science and software engineering, you will enjoy reading this Tweeter thread:
@marcoskirsch @codinghorror Phil said it, I reported it, someone else added on the “off-by-one”.
— Tim Bray (@timbray) August 31, 2014
Clearly, these statements bear some amount of humor and sarcasm, but naming is indeed very important in software engineering.
In his Clean Code book, Uncle Bob stated the following:
Classes and objects should have noun or noun phrase names like Customer, WikiPage, Account, and AddressParser. Avoid words like Manager, Processor, Data, or Info in the name of a class. A class name should not be a verb.Robert Martin. Clean Code
I must admit that I myself sometimes violate this “rule”, especially when it comes to “managers”. I think that I could find reasonable use-cases for many other general post-fixes too.
However, there are two words that I find universally bad in any context: “component” and “module”. The worst part of it is that these two bad names often come bundled together in frameworks and libraries.
Let’s review two real examples of usage of “component” and “module” words from two totally different frameworks, and see how the respective classes could be renamed.
Components and modules in Dagger dependency injection library:
Consider this description of part of Dagger’s functionality:
Hierarchy of components can be established either through components dependencies, or through sub-components. Each component uses one or more modules. In addition to access to dependencies provided by its own modules, sub-component also gets access to all dependencies provided by all modules that its parent components use.
If you used Dagger or any other dependency injection library that uses similar terminology, the above statement might sound perfectly sensible and clear. For an inexperienced developer who just tries to get his head around Dagger, however, the above statement is meaningless without additional (broad) context.
In contrast, consider this description that uses “injector” instead of “component” and “dependency provider” instead of “module”:
Hierarchy of injectors can be established either through injector dependencies, or through sub-injectors. Each injector uses one or more dependency providers. In addition to access to dependencies provided by its own dependency providers, sub-injectors also gets access to all dependencies provided by all dependency providers that its parent injectors use.
From my own experience of explaining how Dagger works to many developers, I know that the second description that uses “injectors” and “dependency providers” is much better. This simple terminology change saves hours of explanations.
Components and modules in Angular framework:
If you are not familiar with Angular, stop for a moment and try to guess what functionality is associated with components and modules in Angular.
The funny part about components in Angular is that the section that describes them in the official documentation start with this sentence:
A component controls a patch of screen called a view.Angular Architecture Overview
I can’t understand why would anybody name a thing “component”, while the very first line of its description screams “view controller”.
And yes, that’s what Angular components are – plain old view controllers.
Modules in Angular are named not as bad as components, but there is still room for improvement. This is the very first sentence of modules description:
Angular apps are modular and Angular has its own modularity system called NgModules.Angular Architecture Overview
Doesn’t say much, right? Consider this alternative description:
Angular apps are modular and Angular has its own modularity system called NgObjectContainers.
Now it is much easier to guess what these entities do, right?
We saw that “component” and “module” are generally meaningless terms when it comes to class naming, yet they are widely used.
While used in different contexts, “component” and “module” words often refer to completely different concepts which lead to confusion among developers that adopt new technologies.
We have seen that it is often possible to choose much better names that describe the functionality encapsulated by the classes.
My advice to all framework and libraries designers is: never use “component” and “module” in class names.
In addition to making it easier for your users to understand what your frameworks and libraries do, it will also make it easier us, bloggers, to write tutorials. We will be able to use statements like “the main components of this framework…” without sounding silly.