So Should You Document Software?
By: Eugene Marin
Tags: Software Development, Documentation

The Case

Ignoring cases when your company or team must abide by certain ISO standards, the case for documentation is usually believed to be pure altruism. Helping those that come later. I’d take a different approach, as altruism just doesn’t impress us busy engineers: We need documentation. For our own work. And not just some day, but also now.

“But what’s in it for me?” you might ask. Well, the same can be asked about unit tests — they take time to write and don’t seem to really benefit you in the short term. But in both cases you get a stamp of confidence, that you knew what you were doing. And much more.

Let’s dive in then. Here are the 3 main ways your documentation will benefit you.

1. Rethinking Your Application

When you write, you think. And no, not in the same way as when you write code. You’re forced to explain what you’ve done in plain language, which forces you to rethink all aspects of the solution. In order to communicate the complex ideas your code implements, you have to phrase them abstractly and precisely. It’s not easy, but it’s an acquired skill. Writing documentation puts you in the reader’s shoes in a way that code, unfortunately, just doesn’t.

Being the first reader of your document, you will also see problems in your application while documenting. Big or small, there will always be at least a couple. Confusing APIs, scenarios you might have missed, possible ways to do things better. Because you’re forced to “zoom out” and explain the big picture, you might discover the ways in which your solution doesn’t really live up to the principles we aspire to, like separation of concerns, single responsibility etc. It is true both for a little high level draft, and for a detailed technical design, where you will rethink the implementation, from module names to edge cases.

The same is true for comments: A good way to test that your code makes sense is to try to describe the goal of each code unit, like a function or class, with one sentence. Everything in the unit must be part of that goal, and everything related to that goal must be part of (or used by) that unit. Can’t do it? Then rethink the unit and/or the goal.

Critics of the traditional documentation process might say it actually lets you get away with not following the principles, or bind you to a bad solution. From my experience, it’s usually the other way around: Not writing documentation doesn’t allow you to see how you could actually write a better code, and as a result you’re left with a code that’s no better quality, but also undocumented. Everyone’s afraid to mess with it, because we’re just not sure why it’s the way it is. We all love it when the code is self descriptive, but on a growing scale where theory meets reality, your document will be there.

2. Summarizing Topics

Documents are always broken into topics, which naturally centralize some aspects of the application that are otherwise distributed and lost in the code. Aspects like configuration capabilities, monitored parameters, security, logging, and so on. This characteristic will save you and others a ton of time when looking for an answer to a “high level” question, like “Which APIs’ availability affects this service and how?”

UMLs, by the way, are great summaries in and of themselves. You can answer a question like that by looking at a picture. Or as one might say, a picture is worth 4 hours of reading code (more like days).

The critics often say that technical documentation is useless because nobody’s going to read a 25 page design. That’s true, but what’s also true is that nobody needs to — we have the table of contents for that. If you want the background and basic idea behind the feature, you read the first page. If you need the configuration capabilities — you go straight to the configurations section on page 9.

3. An Otherwise Lost Knowledge

There will always be things that code alone cannot explain. Things you might just know, but will forget shortly. From technical details like setting up a working environment for debugging, evaluated performance limitations or troubleshooting hints, to the very meaning of the components and terms in the application. Terms that might be the most talked about and understood today, but will sound alien to many of your teammates, and perhaps to you too, in less than a year. No “common knowledge” is eternal. The simplest ideas become forgotten, and the smartest people get confused.

When I think about the times I read someone’s code, which was not necessarily badly written, just trying to “get into their head” and figure what they meant by “Discovery,” or “Channel,” I would always wish having a document where I could just search for where it’s written in plain English. But forget someone else: If someone asks you what these terms mean in your project, you have a beautiful explanation you’ve already worded to yourself, and it’s also in a document you can refer people to. It won’t cover everything, but you can cover enough for a big initial boost.