Clean Code Series: Part 3 – 4 Clean Code Naming Principles Every Developer Needs to Know

John / February 24, 2016 in 

As we continue our discussion of Clean Code, I’d like to begin by asking you a question…What book do you think best serves as a daily reference for improving the readability and understandability of our code?

Is it Clean Code? Pragmatic Programmer? What if I told you there’s a daily reference possibly more influential than any popular programming book, and better yet – you probably already have access to a copy. What book do you think that would be?

A thesaurus.

Clean Code Naming: What’s in a name?

Perhaps the most fundamental choice a developer makes when writing code is what to name things. We assign names to classes, functions, variables, interfaces, … practically everything except the syntax and literals of the chosen language!

Of all the suggestions for better code you may read about, probably the greatest reward, least risk change you can make, is to choose good names. Why? Without good clean code naming techniques, our code will never be easily read or understood, and as we said earlier, that means we can’t maintain or extend it effectively.

Time spent choosing good names can save other developers hours of deciphering code. How does one go about using clean code naming principles? And what makes a name “good” anyway?

Today we’ll cover four guidelines and demonstrate how to apply them using a case study. These guidelines should kick-start your clean code naming ability – though if you’re like me, you still might need that thesaurus!

1. Names should make purpose clear

Say out loud what the name represents and see if you can express that succinctly. The object’s intended purpose should be understood immediately by its name. The name should give an indication about how the named entity is to be used in the system. It should fit within the context of what the larger body of code is about.

Let’s demonstrate this with an example – an implementation of Conway’s Game of Life. If you’re not familiar, the “game” isn’t really much competition. It’s simply a fun simulation of cells on a two dimensional grid that live or die according to a set of rules over a sequence of time steps. Check out an example to see for yourself. Naturally, a starting point for such a problem might be this:


public class Coordinate {
  private int x;
  private int y;
  private boolean isAlive;
  ...

This certainly has some promise. It’s clean and simple, for sure, but I’d posit that the class name can be improved. While a cell might best be represented as a set of coordinates, don’t expose implementation so easily. It makes more sense to use names that exist within the context of the problem the code is solving.

In this case, a better name could be Cell. When we use names that come from the problem domain rather than spelling out the implementation details, we make the purpose clear.

You might also have a driver for the game with a constructor like so:


public GameStateManager(GameState state) {
  this.state = state
}

When you’ve captured the meaning and created a name, inspect it for “noise” words. You might be tempted to call the class maintaining the game’s state something like GameState and you might even have a driver class, GameStateManager. But resist the temptation to pad your names with “noise” words that don’t really add meaning.

Each part of the name should have purpose. The driver could just be simple, Game, whose state is kept by the Board class. If you prefer something that works better with the living and growing idea of the game, Generation could also work for the state of the game.

2. Choose names that are scope-appropriate

Function name length should decrease as scope increases

Use longer names for functions that have small scope and are called from only a few places. These names can be fairly explicit about what they do and given that they won’t be used all across the code base, there’s no problem being more verbose than you might normally be.

Functions with longer names should naturally be self-documented by their name. If made appropriately small, the entire method body can be easily understood by its name. When using this clean code naming principle, a comment should not be necessary.

Here are a couple examples where expanding the name of a private function a bit can give clarity and become self-documenting code:


private boolean living(Cell c) →
private boolean isCellAlive(Cell c)

private int neighborCount(Cell c) → 
private int countLivingNeighbors(Cell c)

Functions whose scopes are much larger and whose behavior is more complex should get simpler and more concise names. It sounds odd, but if you are driving for smaller functions, these higher level functions will be composed of smaller scoped, more specifically named, sub-functions.

An example of a higher-level function in the game, one where a short name would be appropriate would be the public method that moves the game from one state to another. Naming this method tick or evolve seems appropriate. Long names for this function, say calculateNextGeneration or findCellsLivingInNextGeneration, while both clear, are unnecessarily complex for the primary entry point for a user of the game–a method that will be called numerous times.

Variable name length should increase as scope increases

Variables follow the opposite scope rule as functions: The smaller the scope, the shorter the name can be. Single letter variable names are rarely appropriate—except as local variables in small methods or loops. It’s in these contexts that the variables purpose is immediately evident. Even if slightly unclear, the reader won’t have to go far to find the variable’s declaration.

Variables which are used many places in a code base should have names that are long enough to be searchable and understandable. In these cases, the reader will likely have to use their IDE to find the variable’s declaration and it would be best if that wasn’t necessary at all. When a variable has wide use, make sure it’s purpose and contents are clear from its name.


for (Cell cellToEvaluate: getLivingCells()) {
  int numberOfLivingNeighbors = countLivingNeighbors(cellToEvaluate);
  if (numberOfLivingNeighbors == 2 || numberOfLivingNeighbors == 3) {
    ng.add(cellToExamine);
  }
}

for (Cell cell: getLivingCells()) {
  int count = countLivingNeighbors(cell);
  if (count == 2 || count == 3) {
    nextGeneration.add(cell);
  }
}

Notice above the unnecessary length of the local variables cellToEvaluate and numberOfLivingNeighbors. Once they’re shortened, things read easier without loss of clarity. The class variable nextGeneration however, benefits from a longer name.

3. Use the appropriate part of speech

To follow clean code naming principles, classes should have noun or noun-phrases for names: Cell, Board, Game. Function names should be verbs or verb-phrases: parse, addSurvivors, addBornCells. Standard Java practice using getters and setters should use the get and set prefixes. Functions that return booleans should use is or has as a prefix to their names: isCellLiving.

4. Don’t be afraid to rename!

Choosing good names is hard. Even with all this advice (and a thesaurus) there will be times when a good name just isn’t coming to you, and we just pick one. That’s ok.

Other times, a name will seem perfect at first, but later prove to be a poor choice. In both of these situations, and anything in between, we shouldn’t think twice about renaming. With modern IDEs, it’s just a few keystrokes away, and they do all the heavy lifting for you. So do your best, keep these clean code naming guidelines in mind, and fear not.

Stay Tuned…

Hopefully you’ve found these clean code naming guidelines to be helpful and a great way to kick-start your naming ability! Next week we’ll take a deeper dive into not only using functions, but how to use them well. Stay tuned!


Read the Other Parts of the Clean Code Series:

Previous

Clean Code Series: Part 2 – Why Clean Code is Important

Next

Clean Code Series: Part 4 – What Every Software Engineer Ought To Know About Functions

Close Form

Enjoy our Blog?

Then stay up-to-date with our latest posts delivered right to your inbox.

  • This field is for validation purposes and should be left unchanged.

Or catch us on social media

Stay in Touch

Whether we’re honing our craft, hanging out with our team, or volunteering in the community, we invite you to keep tabs on us.

  • This field is for validation purposes and should be left unchanged.