Programmers and project managers sometimes think the phrase "doc-driven development" means putting a lot of comments in code or working closely with doc writers as development happens. That's because it's hard to imagine how development can possibly happen after documentation, because surely documentation can't happen until there's something to actually document.
Documentation traditionally is seen as a sort of journalistic endeavor. Doc writers are given some software, and they take it into the lab and poke it and prod it until they've figured it all out, then they write it down for everyone else to never read.
This misses the all-important process that happens naturally when a developer, idly sipping coffee one evening, drums up an idea for an application. The developer may not realize it, but as the idea formulates, there's a kind of documentation happening already. Ideas don't just appear fully formed with every detail mapped out in a tidy blueprint ready to be hooked up to lonely lines of code. Ideas happen gradually.
Code is arguably an art form, so here's an analogy set in the art world.
A still-life painting represents something in the physical world. But still-life art starts with abstract shapes at first, then gets refined into something recognizable, and then gets texture added, and shading, and so on.
This process could be called self-documenting, because at each stage of the painting's lifecycle, you have a snapshot of how the painting has progressed.
In code, these snapshots might be git commits plus really good comments. While that's great for other coders who drop in later and want to understand what part of the codebase is responsible for which task, it's not generally useful to the average end user.
In the still-life analogy, this means that while the self-documentation of a painting might be useful to an aspiring artist, it doesn't do much for the intended audience.
The end-user documentation of the painting is actually the end result: The thing the artist looked at while painting is the fully realized image that the painting is meant to capture. Should the "end user" of the painting ever want to understand the subject of the painting in its truest form, the end user refers to the actual, physical object.
Believe it or not, the same is true for code. The only difference is that the application being documented does not yet exist. But that hardly means you can't document it as if though it did.
Writing the documentation for the application you want
When you sit down to write an application, you have some idea of what you intend the application to do. I'll use the utility trashy as an example because it's narrow in scope:
Trashy is a command-line trash bin.
That's often exactly where a developer starts, but if you practice doc-driven development, it's where your main page or user manual starts, and it happens well before you sit down to code.
If your only mission statement is "write a command-line trash can," then your code is likely to go in whatever direction happens to hit you first. You may or may not know about the Free Desktop trash specification, so you might not think at first to follow its scheme. You'd probably know that there's already a trash mechanism, so your first iteration of your code would probably just dump a file into the user's established trash bin without any regard for the associated metadata that ought to accompany it.
But if you sit down and document it first, you're forced to think about minutiae. For instance, imagine this as the first draft of documentation for trashy:
Trashy is a command-line trash bin.
trash foo : moves foo to system trash
trash empty : empties system trash
Already it's more robust than the original notion because it also provides a mechanism to empty the trash bin, rather than just sending a file to it. And the only reason it's there is because the act of documenting how a user interacts with your application forces you to think of the application from the user's perspective.
It's a dry run of the difference between painting something and actually hanging that painting on a gallery wall for other people to see.
Documentation as a framework
As you continue to write documentation for your command-line trash application, you eventually come up with other "obvious" expectations that you, as a user rather than a developer, would have for such a tool. You think of conventions, like having the ability to list what files are currently in the trash bin, or even restoring a file that was moved to the trash bin by mistake (which, in turn, would probably lead you to the Free Desktop trash spec, which would educate you about the metadata you should be writing along with your files when they're moved to the trash bin).
Better still, your documentation is now your pseudo code. Your application development has gone from writing code that gets thrown out when you do your first revision to having the skeleton of your code ready to build upon:
while [ True ]; do
# trash --help: print a help message
if [ "$1" = "--help" -o "$1" = "-h" ]; then
echo " "
echo "trash [--empty|--list|--restore|--version] foo"
echo " "
# trash --list: list files in trash
elif [ "$1" = "--list" -o "$1" = "-l" ]; then
# trash --version: print version
elif [ "$1" = "--version" -o "$1" = "-w" -o "$1" = "--which" ]; then
# trash --empty
elif [ "$1" = "--empty" -o "$1" = "-e" -o "$1" = "--pitch" ]; then
# trash --restore: restore a file to original location
elif [ "$1" = "--restore" -o "$1" = "-r" ]; then
# trashy foo: moves foo to trash
# more code here...
Documentation as a roadmap
This has been a simplified example, but for a larger project the principles are even more important, and often the docs come from somebody who isn't also the developer. The result is a more focused development cycle because instead of rumbling toward a vague idea of an application, developers code toward a specific blueprint of exactly how an application is meant to work. Every menu, every button, every contextual menu has already been mapped out in the imaginary application's documentation. All the developers need to do is fill in the code.
Agile road warriors
If all of this sounds very prescribed and inflexible, don't make the assumption that driving development with documentation is not up to the agile challenge. The agile method of development needs feedback from users and stakeholders to guide the direction of what's developed next. Documentation doesn't change that. In fact, in the best doc-driven dev environment, the documentation itself is treated exactly the same as source code. It gets committed to the same repository as the rest of the sources, and it gets updated before anything else.
In fact, treating documentation as the first tier of bug reports and feature requests is a great way to shield a project against UI creep. When a user asks for a seemingly innocuous UI change in what surely is a pool of several other seemingly innocuous changes, a UI can quickly start bearing the classic mark of something designed by committee. That's because, if programmers add everything requested without vetting it through someone with a view of the big picture, in effect it has been.
Using documentation as a part of the ongoing design process makes sense. It's cheap prototyping. Five bugs requesting one new button on a main panel meant to be a clean, one-button start panel equates to six buttons cluttering a once minimal and clean slate. But they don't make it off the printed page if the start panel was documented and reviewed first.
Documentation, just like coding, isn't a one-time process done early in an application's lifecycle. Your project documentation is a living document, same as code, constantly updated and revised to reflect both the development plans and the current state of the project.
Documentation tends to produce consistency in how an application works because the internal logic is mapped out well in advance.
It's easy to code one function as a button click during the first week of an application's development, then relegate an equally important function to an obscure right-click menu during week eight when space in the UI is at a premium.
It's harder to do that when you're writing documentation for something that has no real estate yet. It's all imaginary during the documentation phase, so you'll see the breach of logic in providing a button for one task but hiding a related task. It doesn't get left that way for long when all it costs to fix it is a quick rewrite of a paragraph, which is quite different from changing several blocks of code across many files—and potentially reworking the entire UI that you already spent weeks perfecting. When you're just documenting, you can write anything you want; it's a low-cost repair, and in the end it provides a better, smarter blueprint for developers to build toward.
Test drive a doc today
Possibly the greatest thing about doc-driven development is that there is no barrier to entry. Any non-coder can invent documentation for an application that doesn't exist, and it's surprisingly useful. The applications I've written in the film industry and education sector have all been designed by someone other than me. Sure, there's still back-and-forth user testing and refinement of something that looked good on paper but ultimately didn't work quite as smoothly as the designer had hoped, but it's far less than something without a designer. And sure, there have been times when a non-coder dreams up something way out of scope and has to be reeled in, but sometimes it's led to the developer learning some new tricks to make something actually work that was previously thought out of reach.
Whether you're a developer or just a user with some good ideas, sit down and drum up some documentation for an application that you'd like to see. Alternatively, write some docs for a version of an existing application that you think could be better. You'll be surprised at just how much it affects the way you think about software, intuitive design, and development.