Programmer Maturity Model: Writing Code for Humans

I see too much code that solves problems and mostly works, but it’s written in a way that makes it unnecessarily hard for other programmers to understand.

One would think that it’s a matter of experience and hence it’s a given that programmers with 5+ years of experience would naturally become better at writing easy to understand code, but based on what I run into, it’s far from the truth. I’ve seen many developers with over a decade of experience still failing at this.

Since we spend much more time reading code than writing it, code clarity is very important and should not be underestimated.

Programmer Maturity Model

Thinking about this topic, I came up with a programmer maturity model that’s inspired by the REST maturity model. It’s based on the quality of code a programmer produces.

Level 0: Complete Mess That Doesn’t Work and No One Can Comprehend

Code on this level is being written either by total beginners that are just starting their beautiful journey into the programming world or by total morons with years of experience that are incapable of evolving further.

Code on this level is not just a total clusterfuck that no sane programmer can or even wants to comprehend, but it also doesn’t work. I don’t mean code that has a few bugs in it; I mean code that doesn’t work at all. It either doesn’t compile, fails during runtime, or something else — but it doesn’t do what the programmer wants it to do. Basically, it’s just useless.

In the case of beginners, it’s understandable. We’ve all been there. It takes some time to learn how to write code that does what you want it to.

The amount of time a beginner is stuck on this level differs based on how smart they are. It could be a week or a few months. But it is inevitable. Every programmer goes through this.

In the case of morons, if they’ve been stuck on this level for years, I don’t know how they even manage to find jobs or keep them. Maybe they manage to get a job at some huge corporation where they’re invisible and no one even knows they’re on payroll. Maybe everyone thinks they’re a janitor and yet they manage to collect a junior programmer’s salary. Who knows, who knows.

It must be a struggle to stay on this level after years of experience though. And it’s probably not worth it. Not everyone is smart enough to even grasp the basics of programming. And if that’s the case, why bother? Everyone is great at something. It’s time to give up and try something else.

Level 1: Messy Code That Works but No One Can Understand How and Why

Eventually, at some point, a beginner figures out how to make their code do what they intend. Unless they’re a moron, of course.

This is the level where a person can start being called a programmer. They can get a job and start solving real problems. Life’s good.

Programmers on this level and not very productive but they produce working code. That’s enough for many companies looking for cheap labor that don’t care much about maintainability.

Since programmers on this level end up getting a real job and work in a team with others, at some point colleagues have to read and fix their code. And that’s when a great saga of WTFs begin.

For instance, I’ve seen a method like this:

class Page {
    public int[] getPageCount() {
        // ...
    }
}

That code works fine. It solves a real problem.

But what the actual fuck? I wouldn’t ever expect a method with the word “count” in its name to return an array. I’d only expect an integer being returned.

It’s either a wrong method that should not even be there because the problem needs to be solved in another layer, or it’s just poorly named.

There’s a pet peeve I have. It looks like this:

class User {
    public long getUserId() {
        // ...
    }
}

It’s a User class. It contains properties and methods related to users. Why the fuck do you name the getter as getUserId()? getId() would’ve been more than enough. It is assumed that getId() means “get ID of the user”. Why do “get user ID of the user”?

Or this:

class VerificationCode {
    public String getCode() {
        // ...
    }
}

What the fuck? I mean, does a verification code contain a code? Or is the verification code itself is a code? If it is, how can you get a code from a code? What you want is the ID/value of that code. So fucking name the method as getId() or getValue().

Little things, little things. I know.

It’s not a big deal, right? I mean, the code works. What am I so unhappy about?

Yeah, it’s not that big deal when it’s the only problem in the codebase. But when programmers on this level go unchecked and keep producing code like this at a rate faster than you can spot and refactor it, eventually you see thousands of little things like that.

And that’s when it does become a real problem because code like that generates a ton of WTFs on a daily basis. It significantly slows down development and maintenance. It’s a death by a thousand little cuts.

Level 2: Messy Code That Works with a Ton of Comments to Explain How and Why

Shitty code with comments is better than shitty code without comments, right? Well, not necessarily, but we’ll discuss that a bit later.

To alleviate the problem of other programmers spending too much time comprehending shitty uncommented code, the programmer starts writing comments. Lots of them.

They still produce incomprehensible shitty code that generates a ton of WTFs. They still write methods with hundreds of lines of code but at least there’s a comment every few lines explaining what’s going on.

Sometimes though they get so crazy with comments that you start seeing comments everywhere — even when they’re not needed at all:

/**
 * User class
 * 
 * This class stores all the fields of a user of our system. It also provides getters and setters.
 */
class User {
    /**
     * ID field
     * 
     * It stores the ID of the user.
     */
    private Long id;

    /**
     * ID getter
     * 
     * Returns the ID of the user. 
     * 
     * @return The ID of the user
     */
    public Long getId() {
        // Here we return the ID — as promised by the contract
        return id;
    }

    /**
     * ID setter
     * 
     * Sets the ID of the user.
     * 
     * @param id The ID of the user
     */
    public void setId(Long id) {
        // Here we assign the ID argument to the ID field
        this.id = id;
        // Since this method's return type is void, we don't return anything
    }

    // ...
}

I don’t know about you, but comments like that piss me the fuck off. But anyway.

The programmer comments the shit out of the code base. Sometimes they produce more comments than code.

But at least whenever another programmer needs to fix a bug in code like that, they know exactly what’s going on. Provided the comments are actually up to date.

But that’s the trick about comments. They’re not real code. They’re are ignored by the compiler. And hence they get out of sync with reality. They become outdated.

Irrelevant comments are worse than no comments. Irrelevant comments only create more WTFs.

You read a comment before a block of code. Okay, now you know what it is about. You starting reading the code itself. Hmm… It doesn’t seem to be actually doing what the comment says it does. WTF.

Is the comment being wrong the problem? Or am I just not understanding the code properly? WTF.

Okay, looks like the comment is outdated. I’ll just remove or update it.

Now I finally focus on the code itself. Hm… WT actual F?

See? There was at least one additional WTF because of an irrelevant comment. Without that comment, there would only be WTFs because of the messy code, but comments added an extra WTF or two.

Yeah, theoretically it is possible to keep comments in sync with the code they comment, but in reality it doesn’t happen. Especially when code is being written and refactored by programmers on this level of maturity.

Level 3: Beautiful Clean Code That Works and Is Self Documenting

This is the highest level of programmer maturity.

The code is well structured and SOLID. Classes, names, and variables/constants are named properly to describe what exactly they represent.

Each class solves a single well defined problem and its name makes it clear what that problem is. Since each class is very focused, it only has one type of reasons to change.

There are no long methods with many commented blocks of code in each because those blocks are extracted into methods with clear names that make comments unnecessary.

Code like this reads as easy as a well written book or blog post. You get into the state of flow and can read a lot of it in one go because there are no WTFs that keep knocking you out.

There’s a correlation between writing and coding. If a programmer can write easy to follow text, they can write easy to follow code. I guess it’s the same part of the brain that’s responsible for both. It’s about clearly structuring and expressing your ideas to other people.

Not every programmer reaches this level of maturity in their whole career. The same way as not every person learns how to clearly express their thoughts in writing.

Most programmers get stuck on Level 2.

I wish there were more programmers on this level of maturity, but in reality they’re a small minority and are hard to find. If most programmers were on this level, the overall state of the whole software industry would’ve been on a completely different level.

One of the reasons we don’t have many programmers on this level is because it depends on intellect. Intellect is a physical hardware limitation that you can do nothing about. You’re either born with high intellect or you aren’t. It’s the same as how tall you are. No amount of wishful thinking will make you taller.

Given that the barrier to entry into programming gets lower and lower, we get more and more not very bright people entering the industry. And hence there’s an even lower ratio of programmers on this level.

Another reason is that even though there are programmers capable of reaching this level of maturity, many don’t even know it exists and hence don’t strive to get here.

And the whole Agile push to produce more code faster doesn’t help here neither.

Published by

Elnur Abdurrakhimov

Elnur Abdurrakhimov is a software architect and developer with over a decade of real world experience.