lastminute.com logo

Technology

Clean Code: meaningful names

fabrizio_duroni
fabrizio duroni

Naming things is one of the most difficult part of our job, still it is one of the more effective way to communicate the intention of a piece of code. Take a look to a real example.


At lastminute.com group we care about the software we developed. We also always though that what makes a real professional software developer is how much he/she care about the software he/she is creating: the approach to the problem, the attention to details in code, the passion put into creating every single line of code, the focus on the mission to solve his/her customer problems with your software.
In fact at lastminute.com group we try to follow an approach called clean code, created by Robert Cecil Martin, known as “Uncle Bob”, and famous also to be the guy that invented the SOLID principles. In this blog post I will talk about one of the main principles of clean code: meaningful naming.

Uncle bob meaningful names

As stated by Uncle Bob in the beautiful meme above, this principle is simple: choose your name carefully. But what does it really mean to “choose carefully”? emoji-confused. Choosing the right names means the following thing:

  • Names should releal intent. Names should answer why a variable, a class or a method exists, what it does and how it must be used.
  • Avoid disinformation. Names should not contains false clues about the scope of a variable, method or class. Taking an example from Uncle Bob’s clean code: “Do not refer to a grouping of accounts as an accountList, unless it is actually a list…So accountGroups or just plain accounts would be better”.
  • Don’t use noise words. Adding in the name something like “Info” , “Data” doesn’t give you any value.
  • Use pronounceable names. This is simple: use names that humans can pronounce without feeling stupid.
  • Use searchable names. Avoid single-letter names and numeric constants that make your components harder to find.
  • Avoid encodings. Avoid unnecessary encoding notation, like for example Hungarian Notation in which the name of a variable or function indicates its type.
  • Avoid member prefix. Don’t add unnecessary name prefix.
  • Avoid encoding interface and implementations. Avoid encoding interface with “I” and concrete implementation with “Impl”. If you really need to encode, do it for the implementation.
  • Use noun or noun phrase for classes.
  • Use verb or verb phrase for methods.
  • One word per concept. Choose a word for a concept and always use it each time you have to refer to it in code.
  • Use solution domain names. Your code will be read by other programmers. Math names, algorithm names, pattern names are all good choices.
  • Use problem domain names. If no “programmer oriented name” exists, go with names taken from the problem domain.

Let’s see an example to understand the real value of naming classes, methods, functions and variable in the right way. For example, take a look at the following C++ code:

struct pt {
    float x;
    float y;
    float z;
};

struct mt {
public:
    float m[4][4];
};

class Obj {
public:
    bool act;
    mt matr;
    std::vector<pt> ms;
};

class GameManager {
public:

    GameManager(std::vector<Obj> anObjList){
        objList = anObjList;
    }

    std::vector<Obj> get() {
        std::vector<Obj> newObjList;
        for (auto currObj : newObjList) {
            if (currObj.act && currObj.ms.size() > 0) {
                newObjList.push_back(currObj);
            }
        }
        return newObjList;
    }

private:

    std::vector<Obj> objList;
};

Even if you can maybe get a feeling of what is going, it’s hard to really understand all the details of this code, and every class, struct is supposed to do and to represent. What are pt and mt???? What is supposed to represent a GameManager and an Obj? And the method get, what wants to get????? emoji-cold_sweat. You can see that a lot of things are a little bit obscure in this code.
We can try to refactor it following the names guidelines we exposed above. Do you think the code will improve in this way? You can judge it by yourself:

struct Point {
    float x;
    float y;
    float z;
};

struct Matrix {
public:
    float values[4][4];
};

class GameObject {
public:
    bool isActive;
    Matrix transformation;
    std::vector<Point> mesh;
};

class Scene {
public:

    Scene(std::vector<GameObject> newGameObjects){
        gameObjects = newGameObjects;
    }

    std::vector<GameObject> getValidGameObjects() {
        std::vector<GameObject> activeGameObjects;
        for (auto gameObject : gameObjects) {
            if (isValid(gameObject)) {
                activeGameObjects.push_back(gameObject);
            }
        }
        return activeGameObjects;
    }

private:

    std::vector<GameObject> gameObjects;

    bool isValid(GameObject gameObject) {
        return gameObject.isActive && isValid(gameObject.mesh);
    }

    bool isValid(std::vector<Point> mesh) {
        return mesh.size() > 0;
    }
};

It’s incredible how the code now seems self explained. Each instruction appears more clear in its intents. Each class, struct and method doesn’t need any additional comment/documentation. I think it’s really amazing how some changes to the names could improve the quality of a piece of code dramatically like in our case. I hope that this article will convince you that the names you choose define how much you code is “beautiful” in terms of readability and also, more import, maintainability. Quoting what Grady Booch said about clean code:

Clean Code reads like a well-written prose.

Choosing the right names is the first step to make your code more similar to a well-written prose.


Read next

A Monorepo Experiment: reuniting a JVM-based codebase

A Monorepo Experiment: reuniting a JVM-based codebase

luigi_noto
luigi noto

Continuing the Monorepo exploration series, we’ll see in action a real-life example of a monorepo for JVM-based languages, implemented with Maven, that runs in continuous integration. The experiment of reuniting a codebase of ~700K lines of code from many projects and shared libraries, into a single repository. [...]

Exploring the Monorepo

Exploring the Monorepo

luigi_noto
luigi noto

Monorepo has become quite popular in Javascript world, and yet not fully explored for JVM-based development. The lack of tools and practical examples slow down its adoption in everyday software projects. In this series of articles, we’ll try to uncover the full potential of a monorepo with Java and Maven. [...]