How to read code without documentation?

Wojciech Milewski
3 min readJun 17, 2019

Writing documentation is painful. You need to keep it in sync with your code, you need to draw nice graphs and diagrams, you need to do it for all 100 microservices. And if your Product Owner pushes you because the deadline is already missed, you may simply forget to write about one corner case. And it may hit you one year later, because “it was not in the documentation!”. And it may hit you hard. And it will.

What if you could never, ever write any documentation at all? But how can I understand code without documentation? Is it even possible?

Well, yes, and here are some tips for you.

Use end-to-end or acceptance¹ tests

Those tests show you responsibilities of an application. They show you the input — how to interact with an application, and the output — what you might expect as a result of the interaction.

Let’s say that you build a service responsible for creating and reading user’s tweets. There are two ways of interaction — you can either get all tweets or post a new one. End-to-end tests would look like:

There is only one input — POST method for adding tweets. You can observe the output of the interaction in GET method for reading tweets.

Thanks to that, you don’t have to document what an application does. It’s already documented (and always up to date) as tests.

Focus on points of integration with “external world”

Software is just a bunch of algorithms “connecting the dots”. The dots are — REST API, external services like Github API, a database used for storing some data or event bus for asynchronous communication. Start with an input (like REST API) and see the flow between the dots.

There are two “dots” — repository and eventPublisher. They are showing you where your data is passed to and what kind of side-effect you might expect. The rest is not so important — there are some corner cases, which don’t change the flow significantly.

This approach helps you to easily build a sequence diagram by yourself and understand how an application works.

Find and use patterns

It’s much easier to look at something similar you already know. We like the moment when we can say “I’ve seen that before!”. When you see usage of DDD, you expect that a Repository will be responsible for storage. When you see a Handle or a Controller you expect that it’s responsible for managing input.

All places related to REST API are named Controller. All places related to access to a database are named Repository. You might expect that other similar components will be named the same way.

How does that help? You don’t have to document the behaviour of those, because you know that already by convention and patterns.

Is that all?

No, of course not. But those three tactics are most helpful to me and actually, they helped me not to write any documentation and easily navigate through code.

¹Most of the time names end-to-end or acceptance means the same thing. Usually, it’s about black-box testing when you pass input and check for output result.

--

--