Just detail can lead to poor documentation

I’ve been around computers long enough to have encountered one problem many times. It’s a problem that seems to be almost built-in to computers: poor documentation. In this article I’ll focus on documentation of code that you use via its source code, e.g. an API, toolkit etc. There are mental tools you possibly already use for writing your code that can help with writing its documentation, and I’ll go through some of these in this article.

Poor documentation

There are many things that can make documentation poor, one of which is thinking that including lots of detail is enough. This detail could have a few different forms, for instance lots of snippets of example code, or long lists of descriptions of methods.

I can understand how documentation like this can happen. The code author has worked hard on some code and has mentally ticked the project off as done. Then they think “Ah, documentation” and have to do this extra, non-code thing. The code is a tempting starting point for this documentation, as it has been the thing they’ve sweated over, it’s clearly visible in their IDE, and it’s the thing that that user will actually use.

Mental models

However, often this code-first approach leads to poor documentation. The reason why is that the user won’t just learn the details of the code. They will need to create a mental model in their heads that provides scaffolding for the detail:

A tree-like diagram showing high level concepts, then low level design details, then code examples.  The code examples are visible; the rest are invisible

The mental model will help them to pick which bit of the code to use in which circumstance. As part of this, they will learn to predict what the code will do.

If you present only the detail (or not enough higher-level stuff), the user will have to reverse-engineer all this stuff for themselves. This can be painful, time-consuming and error-prone. It’s also a process that’s familiar to most, if not all, programmers. It is abductive reasoning – the process by which you try to guess at causes from symptoms. It is the process you use a lot when you’re debugging some code. Please don’t make me use my debugging skills to learn your code.

What first?

You might read the “code-first == bad” sentiment above, then the map of mental model + detail and conclude that I’m suggesting it’s best to always do a breadth-first traversal of the diagram. This is not what I’m suggesting. I’m suggesting a user-first i.e. user-centric approach. What does your user want to do with the code? How will the code help? What is the best way to get the user to the point where they can accomplish their goal using your code? This is simply user experience (UX) thinking applied to users of your source code.

Different users, or similar users but with different goals, might construct only parts of the mental model that they need, or construct it in different ways. If you can, I suggest that you approach things in a similar way to the I of the SOLID principles of software engineeringinterface segregation. Don’t force the user to understand more than they need to, by forcing them to harvest higher-level information from lots of low-level examples, or by bothering about bits of your code they don’t need to use.

Dependencies

It might be that there is no simple way of serialising the web of concepts necessary to explain your code. In order to understand concept A, you first need to understand concept B. However, to understand concept B you first need to understand concept A. There’s a circular dependency between the concepts, which is what makes it hard.

It might be helpful to use a technique that can be used to break circular dependencies in code. You analyse the things involved in the circular dependency, and try to see where the existing things can be broken up into more, smaller, bits. Hopefully this can be done in such a way as there’s no longer a circular dependency.

In the case of source code, the bits might be classes or assemblies. Chopping out a part of a class or assembly into its own new class or assembly might be enough to break the circular dependency.

In the case of concepts, one way to do this is to break the concepts up into introductory parts and then more advanced parts. Hopefully the concepts can be at least introduced without a circular dependency. Once enough things have been introduced, then you can move onto a more advanced part of something, that can now reference an introductory part of something that’s already been covered. You can think of this as gradually lying less and less to the reader. Or, you can think of it of as spiralling outwards – a tight circle through just the introductions of everything, gradually working through increasingly advanced parts of topics.

A 2d representation of a 3d spiral

Summary

It’s easy to think of your code as the most important thing, and have documentation as an outgrowth of that, if it even exists at all. However, taking a user-centric approach will probably work well. It’s likely to seem to be more effort in at least the short term, but putting yourself in your user’s shoes will likely lead to them being more successful, which is one ingredient in your being successful too. It can all be helped using techniques that you may have already developed as a programmer.

2 thoughts on “Just detail can lead to poor documentation

  1. Nice one Bob.

    What are your thoughts on artifacts, such as diagrams, or the YAGNI model of “build documentation in response to questions” rather than preemptively?

    I Love a good bit of documentation, but I do think most of the time, it has to come after the software to combat designing to out-dated specification

    Liked by 1 person

  2. I think that you should use whatever is the most effective and efficient tool for the job, which often means diagrams (like in this post).

    I agree that out-of-date documentation is pants. I guess I’m pragmatic here too – the best approach for a huge enterprise shop might be different to the best approach for a one-man-band.

    As for a question-driven approach, I guess it’s like caches and cache misses. What are the costs (to you as the provider, and to the consumer) for a documentation miss? Do you lose reputation / customers? Will it take you ages to fill the gap? Will it cost you more overall to write documentation in small tasks c.f. bigger batches?

    I expect that, like with caches, it could make sense to sort out the common cases ahead of time and then leave the more obscure / unlikely cases to be on demand.

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s