The software engineer's nemesis
Most developers hate writing design documents. Why? The instructions sound simple: just take the design you have in mind and write it down. Unfortunately, writing good documents proves rather difficult. More often than not, we end up with bad (and I mean terrible) documents that are difficult to read, impossible to maintain, and ultimately useless.
Faced with the overwhelming pile of unintelligible design documents, how could one not become soured to the idea of writing them?
Luckily, writing good design documents is possible. We simply need to learn how.
When thinking about good vs. bad documentation, it’s important to remember why we write these documents.
There’s also my (somewhat) cynical take on writing good documentation: fewer annoying questions! If you have to answer the same question more than once, you might as well write it down and point people to a doc. It’s just makes life easier.
While there are infinitely many versions of the “bad design doc”, a few varieties are particularly common because they are easy to write. Don’t fall into the trap!
How do we write good design documents? Structure.
Separate the design from its development.
Although closely related, the design and the development plan are distinct pieces of information. Yes, we often make design choices based on time and effort of implementation (i.e. the schedule) and the design itself informs which developers work on each task; however, we need to focus on the reader’s perspective. Consider a senior engineer who needs to approve the design of a new feature. Do they really need to see the full-schedule or do they just want to read the design? Similarly, a manager might want to understand the task breakdown and schedule without getting into the weeds of technical details.
Another major benefit to organizing information this way is ease of updates. Schedules change constantly and sifting through the full design to update the project schedule is a pain. Breaking the design into manageable pieces (rather than the ominous Everything Document) is better for both author and reader.
The high level summary should gradually introduce readers to the project by giving context to the problem, highlighting goals, briefly describing the solution, and discussing potential concerns. Be careful not to dive into the details here (we don’t want a depth first design) and make sure to keep any design information very high-level. This document should be easily digestible for anyone unfamiliar with the project.
After the high-level summary, we can get into the meat of the design. The number of these types of pages varies from project to project, but a good rule of thumb is one detailed design page per component. It is reasonable to assume that the reader is familiar with the project or has at least read the high-level summary, so avoid redundancy. In addition to the detailed design, the doc might include more specific requirements, API specifications, performance impacts, potential future improvements, etc.
Once we have the design, we can flesh out implementation logistics in the development plan docs. Most projects need two docs: the task breakdown/schedule and the test plan. I feel these are fairly intuitive documents, so my only advice is this: keep it simple. It is highly likely you will be updating these documents constantly, so make them easy to revise.
Everything I’ve outlined so far is just a starting point. Every project is different and the design documents should reflect that. Ultimately, we just want the document to be both useful and easy to digest. Writing good documentation takes practice and patience, yes, but it shouldn’t be devoid of any creativity. As long as the docs are still effective, impart your own style, especially if that helps motivate you to write them.
This post is inspired by a mini-lecture I presented to the GWU Senior Design class of 2024 while serving as one of their alumni mentors. See the full slides