Skip to main content

Simple code: Naming things

There are two hard things in programming and naming is one them. If you don't believe me ask Martin Fowler https://www.martinfowler.com/bliki/TwoHardThings.html.

In this post I'll be covering some general conventions for naming things to improve readability and understandabilty of the code.

There are lots of things that need a name in programming. Starting from higher abstractions to lower we need to name a project, API or library, we probably need to name the source code repository, when we get to the code we need to name our modules or packages, we give names to classes, objects, interfaces and in those we name our functions or methods and within those we name our variables. Overall a lot of things to name.

TLDR; Basic rule

There's a single basic convention to follow to achiveve better, more descriptive naming of things. Give it a meaningful name i.e. don't use shorthands like gen or single letter variables like a, x, z instead tell what it represents, what it does e.g. generateRandomDate, book, books or findBookByISBN, MongoDBBookRepository.

Variables

Let's start from the lowest abstraction, variables. There's the usual suspects a, b, i, j, x, y that are good names in the right context but generally really bad variable names. The next level contains names like entry, datum, date that are probably ok names within a closed context e.g. a anonymous function or a loop but outside of it probably not so good. Then there are the better names like shoppingCartItem, transactionDetails, creationTimestamp.

There are situations where generally bad variable names are good e.g. when operating in a coordinate system variables x, y and z make perfect sense and should be used. Or i as the array index of a loop or x and xs presenting the head and tail of a collection. These are common conventions that developers recognize and understand.

Functions and methods

Variables are inside functions so let's name a few functions. Same namings as with variables also apply here. Not so good names contain things like do, genRndD. These two could be named e.g. sendEmail and generateRandomDate.

Words are meaningful when naming functions e.g. findEntity vs. getEntity. Find implies that it tries to find something whereas get implies that something that always exists is retrieved. Find can return a entity, null, optional with value or empty etc. and get should always return the requested entity or fail miserably.

Things that functions live in

Classes, objects and interfaces also have the same rules as things inside them. Common naming strategy in the Java world has been to name a interface e.g. BookRepository and the implementing class as BookRepositoryImpl when a better name could be e.g. MongoDBBookRepository. With this type of naming the implementing class has a name that is self descriptive and it tells exactly what database it's implemented for.

Packages and modules

Packages and modules are used to separate things from each other and on the other hand as a way to group things that are related to each other. In a application one could have a package named net.polarcoder.myapp.db or net.polarcoder.myapp.persistence the two have the same meaning (at least in my head) and either is a good choise as long as only one of them is used not both and as long as the package contains only database related things.

The harder choise with packages comes with things that could be placed in any of several packages e.g. a database configuration object could be placed in the database package or it could be placed to a configuration package. Either one being a valid choise a team/project/company/community/language convention should be a guiding rule. Personally I would place it in the database package because it's database related.

Naming in tests

One common pattern I've seen over the years is that naming in tests is not considered at all. Even in situations where a codebase has a good, consistent naming in tests the naming is everything but. In my opinion naming in tests should be done with as much care as in the production code. What's more annoying than a failing test that's written with a poor naming and you have to figure out what's it doing and why it's
failing?


Pay attention to naming in tests. It's just as important because those tests are also meant to be read by another person.

Next part

In the next part I'll be tying this subject to another important aspect, readability.

 

Popular posts from this blog

Sharing to help myself

It's been a while since my last post but I have a good excuse. I've been in a new customer project (well new for me) for two months now and have absorbed a lot of new information on the technology stack and the project itself. This time I'll be sharing a short post about sharing code and how it can help the one who's sharing the code. I'll be giving a real life example of how it happened to me. My story Back when I was implementing first version of my simple-todo REST-service I used Scala and Play framework for the service and specs2 for testing the implementation. Since then I've done a few other implementations of the service but I've continued to use specs2 as a testing framework. I wrote about my implementation and shared the post through various services and as a result someone forked my work and gave me some pointers on how I could improve my tests. That someone was Eric Torreborre  the man behind specs2 framework. I didn't take his ref...

Simple code: Immutability

Immutability is a special thing that in my mind deserves a short explanation and praise. If you're familiar with functional programming you surely recognice the concept of immutability because it's a key ingredient of the paradigm. In the world of object oriented programming it's not as used and as easy to use approach but there are ways to incorporate immutability to parts of the code and I strongly suggest you to do so. Quick intro to immutablity The basic idea of immutability is unchangeable data.  Lets take a example. We have a need to modify a object's property but because the object is immutable we can't just change value but instead we make a copy of the object and while making the copy we provide the new value for the copy. In code it looks something like this. val pencil = Product(name = "Pencil", category = "Office supply") val blackMarker = pencil.copy(name = "Black marker") The same idea can be applied in functions and metho...