Writing code like an email
Communication is a process by which information is exchanged between individuals through a common system of symbols, signs, or behavior. Writing code can easily fit in this definition. Some solutions might be written by one person, but if the product is used and extended it will eventually outgrow that one developer. Best example is Facebook. It was written by Mark Zuckerberg, but now there are many more developers working on it.
That being said, when we write code we are not writing it only for machines to understand, but for other developers too. Code should be as readable as possible because it is a channel of communication between people. And what makes code readable? Well, if the other person understands you then you have succeeded. The shorter it takes that person to understand what you were trying to say, the more readable your code is. So we should strive to keep that time as short as possible.
Break it into small pieces
Did you ever receive an email that is one big chunk of text? If not, you are a lucky one. Big blocks of text are repulsive and intimidating. To make things easy for readers we should break text into short paragraphs that represent a logical whole.
This way readers can quickly go through it without reading everything. If some part of text does not concern them they can easily skip it and see what is in the next part. Even better, if we break it into different chapters, and put descriptive titles, the intention of an email will be as transparent as it can be.
So break your code into smaller classes and methods, break statements into smaller ones, and separate statements with different intentions with empty line. Making an enormously long one-liner is not clever. You may be proud to have done it all in one line, but you just undermined the readability and maintainability of your code. You have just put your preferences in front of your project’s well-being.
Reading a long sentence is a nightmare. Imagine reading “Dancing Lessons for the Advanced in Age” by Bohumil Hrabal and try to comprehend it in one go. It is a 128 page long novel written in one sentence. How about doing that under pressure of deadlines?
Same thing goes for the code. Long statements, long methods, big classes, multiple classes in one file… all that makes code harder to read. We are writing a set of instructions, so it should be as simple as possible. Short methods are easier to understand for other programmers and we should use them instead of long “smart” ones.
Be as straightforward as possible
“The Story” of one class or method should be as straightforward as possible. If you want to say something you should say only that. And the name of the class/method should be descriptive enough to indicate the purpose of it. This may sound silly when put on paper, but in practice it is much harder to stick to it.
For example, writing an email to the client. Let’s say our client is outsourcing some project to us, and we need to arrange code and documentations transfer, and arrange a call for developers to do knowledge transfer. In this case how we format email can be a crucial step determining speed of project transfer. If we write a long text explaining every part in smallest details, this creates a lot of noise. There is a high probability that our client will not read it and we will not get all the necessary information.
Everything will end up in the video call where we will need to repeat all the information from the mail. If we structure it into an email as a list of things there is a better chance that we will get all we need and that call will be unnecessary and everything will be done quicker.
Dear client,
Development of project [name of project] should start next month. To make this possible we need to finish all necessary preparations. We need access to:
- source control
- documentation
- development and test environment
Best regards
And if someone needs additional explanation, they can always ask for it.
What preparations?
Why do you need access to source control? Who needs it?
What kind of documentation do you need?
What kind of access to our environment do you need?
In code this is the equivalent of digging deeper into implementation. If we are analyzing business logic we do not need to know implementation details for fetching data. Is it SQL, NoSQL or something else? It is not important for understanding what the method is doing.
If we put a lot of information in one method it will create a lot of noise. Opening SQL connection, writing SQL query, mapping response to entity class and similar things will distract us from the real purpose of the method. Delegating this to the repository hides all of that from us and helps us focus on important parts.
Do one thing at a time
Let’s do the follow up on the previous section and say we should contact that same client about the developer position that needs to be filled and for this a job interview needs to be arranged. We didn’t finish the previous mail. Do we add an additional paragraph in that email, or should we send it as a new one? It is the same client and most of the people from the first mail should receive this one too.
What subject should we put for mail that contains both topics? “Project transfer and job interview”? We can see that we are doing two things at once. At first it doesn’t seem like a big problem. But imagine when a client starts replying to your mail, adding new recipients. Some of them start answering the first part, others the second part. Now you need to reference that mail, but only part about the job interview. You can’t do that, you are including them in the whole thread. Your dev-ops need the part related to environments. Again, you are including them in the same thread. Everybody receives every email. This is quickly becoming a mess.
Translated into code, this means one thing: classes and methods should have only one responsibility. Keeping it this way we are going to save ourselves a lot of time once the code base becomes big and features start to pile up.
Be descriptive when naming things
I have already touched on this topic in the previous section. When we send an email we need to set a subject. Imagine you receive an email “Important — read”. Or maybe “It is not working”. What is the purpose of this email? We need to open email and read what is inside. Later, when we need to find it between a bunch of emails that we have received, how will we ever know what to search for?
We should have a tendency to set the subject of email short, but as descriptive as possible. This way the recipient can see the intentions of an email just by reading the subject (“Project transfer”, “Job interview”).
Also, when we name things in our code we should follow the same logic. For example, we have a property that determines if a customer can have some feature enabled. I have a tendency to name boolean values like questions (IsDeleted, IsPublished, HasFeatureEnabled…). This way when I write code it would look something like this:
if(customer.HasFeatureEnabled) {
// do something
}
When we read it later we are basically reading plain old English (If customer has feature enabled do something).
If the subject of our email is becoming too big, that is a sign that we are doing too many things at once and that we should probably split it into two or more separate emails. For example, “Project transfer and job interview” mentioned before. This is what I am talking about. You can see that this is something that doesn’t belong together and that will probably lead to unreadable and messy mail thread.
Same goes for code. If the name of a class or method is too big, that is one of the signs that we are doing too many things at once. Changing one thing from that class/method could break other behavior in that same class/method. And good naming convention warned us about it.
Be consistent when naming things
Other important thing that we need to take care of when writing email is consistence. We should use expressions and naming that recipient understand, and stick to it. We shouldn’t juggle with multiple names for same thing, nor name different thing with same name. For example, let’s say we are creating multi tenant software. It is some form of CRM.
Now, our client is a company that has other companies for clients that have people as their clients. In this sentence word client is used to describe three different things, and word company is used to describe two different things. In two cases client and company are the same thing.
If we write an email and talk about a client, who are we referring to? And if we once say client, and other time company we are just complicating things for whoever is reading our email. We should agree how to call something and stick to it.
If something is called Tenant it should be called Tenant in all emails. If we sometimes call it Account, Client or Company, even though it is correct, we didn’t agree on that and it could cause confusion.
Avoid slang
I have a friend that for some particular reason refuses to write full words in a sentence. I always felt like I had a stroke reading his messages. This became so irritating to the point that sometimes I simply would not read his message and would just call him.
Many people write code this way and this eventually leads to two things: 1) you either need to do everything by yourself or 2) you will need to explain your code to the other developers every time someone else is doing changes on it.
When we are debugging code we are scanning through it, not really reading it, but trying to interpret logic behind it. We don’t want to read it all and why should we? We only need a general picture of what is going one and to find the place where things need to be changed.
Let’s say we need to do something by specific instructions. These instructions were sent to us in an email. We find the email thread and start to go through it. We do not read every email in it, we only scan through it to find things that we need. Imagine now that my friend sent us these instructions using made up abbreviations and acronyms. Now again, imagine reading that under pressure of deadlines.
I found a lot of things like this in the code I was working on. Namespace called GTK that has nothing to do with UI, AccService that has nothing to do with Accounts, 8+ letters long names that do not form any meaningful word and look like random generated string… Some of those were mine, some were other programmers’ code. But in the end, in all these cases, it was harder to work on the code than it should be.
Break it early
If some condition will break execution, it should be put first. This way a person does not need to spend the whole day analyzing something that doesn’t refer to their case.
On multiple occasions I received mail that goes something like this:
We are informing you regarding [some actions]. If you already did [that action], or it does not apply to your case, please ignore this email.
[content of mail]
This saved me so much time reading unnecessary mails, and not to mention double guessing myself if I already did requested action.
Conclusion
Writing code is easy. Reading it later, not so much. At the moment when we were writing code we had all the facts in our head and we were fully devoted to the task. But with time that knowledge fades away and we find ourselves in a situation where we need to relearn it. If someone else needs to do the task on our old code and it is not readable, there is a good chance that that task will eventually find its way back to us. This will waste the time of two developers instead of speeding things up. Time is the expensive resource and we should invest some of it now so we can spare it later.