Click here to Skip to main content
15,884,425 members
Articles
Tip/Trick
(untagged)

10 Small Tips for Better Code Readability

Rate me:
Please Sign up or sign in to vote.
4.67/5 (16 votes)
2 Nov 2018CPOL5 min read 18.6K   10   14
Small tips to make your code quality better

Introduction

I can’t stop writing about the importance of code quality and code readability. I think this is one of the most important points in coding. On the other hand, I have already worked for several companies and I sadly realized that the code quality is really poor at most of the companies, even at the famous ones.

In this article, I collected 10 small points. It is not so difficult to follow them and if you are following them, your code will be much more readable. I added some examples in C++, but all these points can be easily adapted to any other object oriented programming language.

Some of you might not agree with my points. First of all, there are some mostly old-fashioned coding styles which contradict with my points. On the other hand, some of these points can be a bit against performance. Of course, there are special cases when not all of these points should be blindly followed. But I think these 10 small points can make your code quality much better. I hope you like the points.

10 Tips and Tricks for Better Code Readability

1. Use the Right Variable/Function Names

The rule in principle is pretty easy, in practise, it is not always so easy: you should call everything based on that what it is. So avoid variables like i, j, x, y, value, return_value, etc. Name your variables and functions well. I present it with an example:

C++
vector<vector<int>> getThem()
{
  vector<vector<int>> vector1;
  for (vector<int>& x : theList)
  {
    if (x[0] == 4)
    {
      vector1.add(x);
    }
  }
  return vector1;
}

Do you not understand what this function is doing now? I’m sure, you have no real idea. Now I changed the names in the function, is it more clear now?

C++
vector<vector<int>> getSelectedCells()
{
  vector<vector<int> selectedCells;
  for (vector<int>& cell : gameBoard)
  {
    if (cell[CELL_VALUES::STATUS_VALUE] == STATUS::SELECTED)
    {
      selectedCells.push_back(cell);
    }
  }
  return selectedCells;
}

What about now? Now it looks like it is collecting the selected cells of a game board. Nothing changed, just the naming. That’s why naming is pretty important.

2. Use Constants Instead of Magic Numbers

Try to avoid the usage of magic numbers in your code, it is making it unreadable. Let me give an example:

C++
int t = x * 24 * 3600 * 365;

Where are these numbers coming from, what does it mean? It’s a bit unclean.

C++
int t = x * hours_per_day * seconds_per_hour * days_per_year;

Is it easier to understand now?
And let’s use what we already learnt in the first point:

C++
int seconds = years * hours_per_day * seconds_per_hour * days_per_year;

Reorganize a bit:

C++
int seconds = years * days_per_year * hours_per_day * seconds_per_hour;

Now it’s much more clear what is it, isn’t?

3. Use Enums Instead of Magic Numbers

In the code of inexperienced programmers, quite often, I come across similar solutions:

C++
switch (status)
{
  case 1:
    //do something
    break;
  case 2:
    //do something
   break;
…
}

Ok, but what is the meaning of status = 2? Who knows. Use rather an enum for status like:

C++
Enum class Status { InProgress, NowAnswer, Error, Ok };

It will make your code much more readable.

4. Give a Name to Complicated Conditions

In most code, there are a lot of complicated conditions, like:

C++
If (line > 5 && line < 100 && feature_enabled && !error_found && value == 5)

In such cases, it is really complicated to figure out what the condition is about. It is a good idea to name the condition and/or the sub conditions. For that, you can either use lambda functions or booleans, like:

C++
bool isLineInRange = line > 5 && line < 100;
bool featureActived = feature_enabled && !error_found;
if (isLineInRange && featureActivated && value == 5)

Now it is much easier to figure out the meaning of the condition.

5. Split Up Your Function TO Smaller Ones

OK, this point is maybe trivial: if you have a function which is too long and/or is doing multiple things, just create smaller functions which are decoupling a part of your function and call them from your function.

6. Do One Only One Thing in Your FunctIons/methods

This is connecting from the previous point. So for example, if you call a function as SaveToFile, I’m expecting from the function that it is saving something to a file and not changing anything on the current data. If you still need to change something on the data, move that part of code to a new function. It’s really important that your function needs to do exactly one thing and nothing more: the thing that is in its name. So for example, in a getter function, don’t do complicated calculations. In that case, just create a separate calculate and save function.

7. Make a Clear Difference Between Functions and Methods

It is a personal opinion, but I’m following this point at coding and I think it makes the code readability really better.

In my understanding, a function is a subprogram with a return value. And in my view, a function should not change the state of the object. So it should not change any object level private/public variable. Just read them, calculate the return value based on them and return. So for example, in C++, they can be marked at const.

The methods are subprograms without return value. So in C++, technically, they are the void functions. The main goal of methods is to change the state of the object. Every change in the status of the object needs to be done by using methods.

8. Organize Your Parameters/variablEs Into Structs

There are several cases when a function has several (3+) parameters. Some functions have a really long parameter list, over 10-15 parameters. When you are calling such functions, it is pretty difficult to figure out which added value belongs to which parameter. That’s why I think it is better to organize your parameters in one or more structs, like:

Instead of:

C++
drawRectangle(double x, double y, double width, 
  double height, int color_r, int color_b, int color_g)

use:

C++
struct Position
{
  Position(double x, double y) :
    x(x),
    y(y)
  {};

  double x;
  double y;
}

struct Size
{
  Size(double width, double height) :
    width(width),
    height(height)
  {};

  double with;
  double height;
}

struct Color
{
  Color(int red, int green, int blue) :
    red(red),
    green(green),
    blue(blue)
    {};
  int red;
  int green;
  int blue;
}

drawRectangle(Position position, Size size, Color color);

So that when you are calling it, instead of:

C++
drawRectangle(100.5, 54.3, 34.5, 23.3, 222, 144, 68);

You can use:

C++
drawRectangle(Position(100.5, 54.3), Size(34.5, 23.3), Color(222, 144, 68));

I think in this way, the meaning of each parameter is much more clear.

9. Convert Functions To Classes if Needed

Especially in old code, there are quite often functions with multiple input and output parameters. In most cases, I would avoid the usage of output parameters. But especially, if there are multiple ones, it is really better if you are creating a class, having all the parameters as private variables. Create setter for inputs and getter for outputs.

10. Cover Your Code With Unit Tests

Unit tests are really useful to verify your program and to avoid regressions. But it is even really good to have unit tests if you would like to understand a code. Simple, you can see for each function and class what is their expected behaviour.

These were my points for this article. I hope you like them, feel free to extend them if you have any other good ideas.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Germany Germany
I'm a software developer with around 5 years experience. Actually my main focuses are the following: software architecture, technical project leading, coaching, quality assurance and C++ development.
Next to that I'm blogging under: http://howtosurviveasaprogrammer.blogspot.com

Comments and Discussions

 
GeneralMy vote of 5 Pin
Pete Lomax Member 106645057-Jan-19 22:25
professionalPete Lomax Member 106645057-Jan-19 22:25 
GeneralRe: My vote of 5 Pin
Marcell Lipp12-Feb-19 21:27
Marcell Lipp12-Feb-19 21:27 
GeneralRe: My vote of 5 Pin
Pete Lomax Member 1066450513-Feb-19 18:03
professionalPete Lomax Member 1066450513-Feb-19 18:03 
GeneralMy vote of 5 Pin
Mark Johnston (SSCGP)6-Nov-18 3:21
Mark Johnston (SSCGP)6-Nov-18 3:21 
SuggestionFunctions and Methods Pin
Stefan_Lang6-Nov-18 2:22
Stefan_Lang6-Nov-18 2:22 
GeneralRe: Functions and Methods Pin
Marcell Lipp7-Nov-18 20:37
Marcell Lipp7-Nov-18 20:37 
GeneralRe: Functions and Methods Pin
Stefan_Lang7-Nov-18 22:28
Stefan_Lang7-Nov-18 22:28 
GeneralRe: Functions and Methods Pin
Marcell Lipp7-Nov-18 22:52
Marcell Lipp7-Nov-18 22:52 
Or you could create a class from your function, something like this:

C++
class DerivateCalculator
{
    public:
        DerivateCalculator(double u, double v); //this one is doing the calculation and set all the output parameters
        
        Point3& point;
        Vector3& deriv_u;
        Vector3& deriv_v;
}


Then you could use it later in the following way:

C++
DerivateCalculator derivates = DerivateCalculator(u, v);
std::cout << "The point is: " << derivates.point << std::endl;
std::cout << "The derivate of u is: " << derivates.deriv_u << std::endl;
std::cout << "The derivate of u is: " << derivates.deriv_v << std::endl;


I see this way more readable and user friendly. Of course it could be even getter with proper getter functions and maybe with lazy loading (so that the calculation will be done first when a getter function is called).
QuestionSingle exit point. Pin
Turner, Pete6-Nov-18 2:18
Turner, Pete6-Nov-18 2:18 
AnswerTips Pin
Alex Steinmetz5-Nov-18 0:29
Alex Steinmetz5-Nov-18 0:29 
PraiseIt's a good list and it's well explained Pin
TaipeiJim4-Nov-18 21:16
TaipeiJim4-Nov-18 21:16 
GeneralGood list for improving readability Pin
madden2-Nov-18 8:11
madden2-Nov-18 8:11 
GeneralInteresting ideas Pin
Hkimgt2-Nov-18 7:40
Hkimgt2-Nov-18 7:40 
GeneralRe: Interesting ideas Pin
MadMyche2-Nov-18 11:26
professionalMadMyche2-Nov-18 11:26 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.