By February 18, 2019

Good Developers Don’t Just Write Good Code

I want to become a good developer.

And I assume that, if you’re reading this, you aspire to become a good developer too.

But what is a good developer, to begin with?

If we reflect on what we need to do in our jobs as software developers to identify what is important—and, therefore, what we have to master in order to become “good developers”—it turns out that one of the main things we do is reading code that other people wrote.

While writing code is important, one of the main things that we do is reading code. Let’s take this from the beginning.

Good Developers Write Good Code

As software developers, our mission is to ship software that works. And what is software made of? Code, of course!

What comes out of this simple analysis is that if you want to be a good developer, you need to be able to write good code.

Fine. But now we’re left with a new question: What is “good code”?

To answer this question, let’s think about what code is useful for. Code is what makes software, and the mission of developers is to make software that works. So, following this, good code is code that works.

Except that there are a hundred ways to write code to make a feature work, but all those ways are not equally good. Note that in code that “works,” I’m also including the fact that it runs fast enough, so I’m not talking about which code has the best algorithmic complexity.

The differences between the various pieces of code that all “work” is their design. So good code is code that has good design.

Bear with me, we’re getting there. We now need to define what “good design” is.

Once we’ve written a piece of code that works, why does its design matter in the first place? It matters if someone is going to come back to this code. Let’s call this someone Bill. Bill can be you or anyone else in the company. Bill can even be someone who is not here yet but will be recruited in the future.

So a good design is a design that will make Bill’s life easier. As a result, a good design needs to be understandable. If we unroll the logic we’ve just built, a good developer can produce code that is understandable. There are many aspects to writing clean code. An important one of them is respecting levels of abstractions.

But this is only a part of the picture. To be a good developer, you also need to do a good job when you are Bill. That is, you need to be able to work with existing code—however well or poorly designed it is.

Good Developers Can Work With Any Code

How much time do you spend writing code every day? Even if you work as a professional software developer, you probably don’t spend all day coding. You probably spend more time reading code than writing it.

Indeed, we read code all the time. We read code to analyze it and think about how to integrate new features. We read code when we debug maintenance issues. We read code during code reviews, when writing documentation, or simply when we help out another developer with their task.

As software developers, we read a lot of code. We spend much more time being Bill than writing code.

As a result, we need to embrace Bill’s responsibilities. On top of writing expressive code to make his life easier, we need to figure out how to work with existing code. And that starts with understanding it.

Understanding Code

On top of giving instructions to the machine, the purpose of code is for a developer to communicate their intent to other developers. Like we said, we write code with good design for Bill to understand.

But there is code out there that is not easy to understand. A good part of this code is what we collectively call “legacy code.” If you’re a software professional, you probably have to work with legacy code.

I’ve worked for over seven years in our industry, I go to a lot of conferences and user groups, some of which I’m an organizer of, and I have a popular blog about writing expressive code. With all this, I get to talk with a lot of developers, and I can tell you one thing: Legacy code is everywhere.

Since a large part of your job is about reading code, and you get to work on tough code, to be a good developer you need to be able to read code you don’t know and quickly make some sense of it.

Fortunately, there are techniques to understand unfamiliar code. Here is a practical one: When you read a function or a method for the first time, start by looking at its end first.

Indeed, functions often have a progression with intermediate objects and actions, which leads to delivering a final result or effect that is located at its end. If you start by looking at that, you’ll get an idea of where the function or method is going, and it will make the reading of the rest that much easier. Sometimes, it will even save you from reading the rest at all, because you’ll have understood what the function is about.

Of course, to know what a function is about, its name and parameters should be enough. But there is code out there where functions don’t have a name as informative as they “should be.”

Peeking at the end of a function or method can save you a great deal of time. This is one of the 10 techniques to understand legacy code that are presented in The Legacy Code Programmer’s Toolbox.

Blaming the Person Who Wrote the Code Is Not the Point

When you’re Bill, if you’re having trouble understanding a code, it can be tempting to blame the person who wrote the code. After all, their job was to write code with good design, and if you can’t make sense of their writing, then they didn’t do such a good job.

You may be right or you may be wrong. Maybe it was a difficult piece of code to write, and we wouldn’t have done a better job if we had written it ourselves. Maybe we’re lacking a piece of context. Or maybe the person who wrote it didn’t find the optimal solution, but after all, who always finds the optimal solution?

The thing is, it doesn’t matter. The code is here, and it’s what you have to work with. Don’t think about whether the writer did a good job or a poor job of designing the code, unless you’re doing this for the explicit purpose of improving the code or improving your skills. Judging the code to criticize it is a natural but primal attitude. And having an irrational, knee-jerk attitude of disgust when reading code won’t get you anything positive. It can only put you and the people who sit around you in a negative mood.

To be efficient in your work, focus on what you can do with that code.

Focus on What Matters

What does matter in your ability to be efficient when working with existing code is what you know about that code. In software engineering, like in many fields, knowledge is power.

There are plenty of ways to increase your knowledge about your codebase. One of them is to write a piece of documentation on a region of code you don’t know.

It can seem surprising at first: If you don’t know a piece of code, how can you write anything about it?

If you start documenting little by little what you discover in a region of code, this will direct your research. By explaining what you just start understanding, you’ll discover questions to be answered in order to complete your explanation. This is very valuable because it gives you specific things to look for in code.

Little by little, your exploration goes from a random one to a directed one, until you know your way around the region of code.

Note that there are plenty of other practical ways to increase your knowledge, and more generally, to be more efficient when working with legacy code.

Good Code Is Still Easier to Work With

Being a good developer is as much about being efficient with existing code as about writing good code.

If we take this idea further, we could even wonder: If we’re spending most of our time in Bill’s role, reading and working with existing code, does it matter much to be able to write good new code after all?

The answer is yes, because the code you produce will be used by Bill. And even if it is Bill’s responsibility to be able to work with any code, you want to make his work as easy as possible.

Writing code is about expressing your intentions more than just writing code that does the job. You send a clear message, your reader opens their eyes wide, and you hope that you guys will meet in the middle.

About the author

Jonathan Boccara

Jonathan has been a C++ software developer for 6 years, working for Murex which is a major software editor in the finance industry. His focus is on C++ and in particular on writing expressive code, with some insights coming from Functional Programming with Haskell as a second language. He blogs regularly about expressive code in C++ on Fluent C++. You can also find him on Twitter @JoBoccara.