This is a mobile version, full one is here.
Yegor Bugayenko
3 March 2020
Prefixed Naming
If you look at the source code of
Takes or
Cactoos for the first time,
you most probably, like many others, will be triggered by the naming
convention, which implies that most class names have two-letter prefixes:
BkSafe
,
RqFake
,
RsWithStatus
,
TkGzip
,
and so on. To be honest,
I haven’t seen a single Java developer who would be comfortable with this
convention at first sight. I have, however, seen many who are in love with it
now. This article is for those who are interested in moving from the
first category to the second one.
Any software package, module, library, or framework of a decent size has a large amount of classes. Well, it has to have. If it doesn’t, there is definitely a problem with its design. So there’s always a problem of how to name those classes. The easiest and most obvious approach is the one used in Java and its flagship framework Spring: make class names as descriptive and as long as possible. Here are some examples:
ObjectFactoryCreatingFactoryBean
SimpleBeanFactoryAwareAspectInstanceFactory
TransactionAwarePersistenceManagerFactoryProxy
AbstractAnnotationConfigDispatcherServletInitializer
This is garbage, isn’t it?
A much more sophisticated and time-consuming way of naming classes is
by the DDD paradigm,
which suggests using nouns after entities in the real world, like port, car,
book, story, user, socket, and so on. Identifying the right entities
is a big challenge for a software architect. A bad one would just resort
to ConnectionFactoryUtils
or DefaultListableBeanFactory
and call it a day.
A more professional one may spend hours or days, but will eventually come up with
something more domain-driven.
Let’s assume you are the latter and you managed to find the right nouns. How many of them will be out there in your domain? A few dozen, I believe. Even if the application is rather complex, you won’t have more than 30 entities in its problem domain. However, as was mentioned above, the amount of classes will be much larger, sometimes over a thousand or more. Thus, the second problem you will face is how to name classes which are “entities with specifiers.” For example, you have a port and also a random port and a TCP port, and a port already closed, and a port not yet opened, and so on.
There will be nouns with adjectives: random port, closed port, opened port,
TCP port, broken port, and so on. How do you name those classes? Maybe, as simply
as this: RandomPort
, OpenedPort
, ClosedPort
, TcpPort
.
Maybe, but I think it’s better to turn the common Port
part into a common prefix Pt
for all classes:
PtRandom
PtOpened
PtClosed
PtTcp
The only disadvantage of this approach is that newcomers may have no idea
what the Pt
prefix means. Indeed, it may take some time (a few minutes) to learn it. However,
the advantage is greater: once you learn all the prefixes that exist
in the application (and there will be just a few of them, since the amount
of entities in the domain is pretty limited), you can immediately understand
which part of the type hierarchy the class belongs to (this one is from
Takes):
Once you see the Rq
prefix you immediately understand that you are dealing with
an implementation of the
org.takes.Request
interface. Not the
ServletRequest
from JDK,
not HttpRequest
from Spring,
and not Request
from OkHttp.
You know that it’s the Request
from Takes!
Thus, by using short prefixes instead of nouns we add clarity to the code. We remove the noise of repeated usage of the same noun over and over again and make referencing easier. Each prefix is a unique locator of a class in the type hierarchy.
Which class name you would use: SynchronizedDatabaseConnection or SncConn?
— Yegor Bugayenko (@yegor256) March 15, 2020