Andy Crouch - Code, Technology & Obfuscation ...

Readable Code Part 5 - Wrapping Up Code Readability

Photo: Unsplash

After a short interlude for an Easter holiday, I wanted to bring to an end my series on readability. This post will look at a few peripheral things to keep in mind when developing readable code.

First up is formatting. Formatting covers a few areas. Line width, Tabs vs Spaces and syntax flow all fall under this.

var user = UnitOfWork.GetRepository<User>().GetAll().Where(u => u.Name.ToLower() == lockedUser.Name.ToLower()).SingleOrDefault();

Vs

var user 
    = UnitOfWork
        .GetRepository<User>()
        .GetAll()
        .Where(u => u.Name.ToLower() == lockedUser.Name.ToLower())
        .SingleOrDefault();

And

public static bool IsFalse(this bool b)
{
    return b == false;
}

Vs

public static bool IsFalse(this bool b)
{
  return b == false;
}

Tabs vs Spaces has been discussed to death and I have never understood the problem. Pick one as a team and stick to it. Splitting your code vertically or horizontally makes no difference to the compiler. But, it can make it easier to read when structured vertically by statement. This is especially helpful with more fluent API’s as shown above. As I have covered in previous posts, the key is consistency. This consistency should be applied across projects and be enforced company-wide. This will help in onboarding developers, code reviews and team productivity. When interviewing you should make a point of asking to see their style guide. If they don’t have one then suggest you would like to lead the development of one if successful. If you don’t agree with some small points in an existing guide then adapt or decide that the use of spaces is just too unreasonable.

Consistent formatting choices lead to agreeing on a code line length. In years gone by a lot of organisations would work to 80 characters per line. This stems from hardware limitations. Today most people have at least Full HD screen resolutions, if not 4k. I would still argue that a shorter line length makes for easier code to read. It also means that you can reduce context switching by having multiple files open in an editor side by side. A lot of editors try and automatically wrap long code lines across multiple lines. This makes code inconsistent and hard to read. I tend to set my max character count per line to 100.

Next I want to cover deep nesting. Deep nesting makes code very hard to read and is normally a code smell. By deep nesting, I mean code such as:

public void foo(object[] args)
{
    if (args != null)
    {
        foreach(var arg in args)
        {
            if (arg != null)
            {
                if(typeof(arg) == String)
                {
                    foreach (char c in arg)
                    {
                        Console.WriteLine(c);
                    }
                }
                else
                {
                    Console.WriteLine(arg);
                }
            }
        }
    }
}

In most cases there is a better way to structure the code. Just breaking the nests down into methods improves the readability.

public void foo(object[] arguments)
{
    if (arguments != null)
        return;

    foreach(var argument in arguments)
    {
        if (argument != null)
            continue;
    
        if(typeof(arg) == String)
            OutputByCharacter(argument);
        else
            Output(argument);
    }
}

private void OutputByCharacter(string argument)
{
    foreach (char character in argument)
    {
        Console.WriteLine(character);
    }
}

private void Output(object argument)
{
    Console.WriteLine(argument);
}

This leads on nicely to Code Grouping. Grouping and ordering of methods and functions by the use of white space should be done in the same manner you would group your paragraphs in prose. Again agree on how you will do this and enforce it. There are different grouping approaches I have seen such as:

  • Grouping by access modifier. This results in all public methods being together and then all protected methods and then all private methods.

  • Grouping by use. This means that public methods are generally defined first along with protected methods. Private methods are generally defined under the first public or protected method that uses it.

I like the second of these approaches. It means that you do not have to scan to the bottom of a source code file to find a private method. It is usually within a few lines of the code that calls it. This means it aids reading and reduces (but does not prevent) context switching. There doesn’t seem to be a best practice around grouping.

Finally, I want to cover source code file organisation. This can sometimes be governed by the framework you use. If it is not then you need to organise files in logical groupings and namespaces to make finding files simple. There are different ways to do this and even approaches such as Clear Architecture. If you have to create your own structure then group related items. One project I have worked on has a Services directory. Within that directory is over 300 business logic and domain related service classes. It is hard to navigate and to find code. Don’t do that.

So that’s, mostly, what I have to say about improving code readability. It comes down to two main things:

  • Write code that is clean, logical and easy to digest. Code is written in a language. Language is a method of communication. Either you or someone else will read your code many times over its lifetime. You do not want to confuse or hide the meaning of the code. Think about Unix and how some systems developed in the 1970s are still in use. That code will have been read thousands of times. Are you happy that your code could survive like that?

  • Any supporting readability guides, formatting or project structures should instil consistency. Work with your team to agree on what you feel is a good level of readability and stick to it. Build checks into your code reviews. Encourage your team if they commit code in a way that is not in line with the guide. Think of your code as words on pages which are your files in the book that is your project.

If you have enjoyed this series or have any opinions around the idea’s I have outlined in these posts please contact me via twitter or email. I would certainly like to discuss them in more depth.