# Doc-Driven Development
by Seth Kenlon

Programmers and project managers sometimes think the term "doc-driven
development" means putting a lot of comments in code, or that it means
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 is, traditionally, seen as a sort of journalistic
endeavour. 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 and
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. A developer may not realise 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 starts with abstract shapes at first, and 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 life cycle, you have a snapshot of how the painting
has progressed.

![Self-documenting art.](docs_painting.jpg)

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-realised
image that the painting is meant to capture. Should the "end user" of
the painting ever wants 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 yet. 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](https://klaatu.fedorapeople.org/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 man page or user manual starts, and it happens well before you sat 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](https://specifications.freedesktop.org/trash-spec/trashspec-1.0.html)
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 experiencing 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 yourself, 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 got moved to the trash bin by mistake (which, in turn, would
probably lead you to the Free Desktop trash spec, educating 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 " "
      exit
   # trash --list: list files in trash
   elif [ "$1" = "--list" -o "$1" = "-l" ]; then
       list
       shift 1
   # trash --version: print version
   elif [ "$1" = "--version" -o "$1" = "-w" -o "$1" = "--which" ]; then
       version
       shift 1
   # trash --empty
   elif [ "$1" = "--empty" -o "$1" = "-e" -o "$1" = "--pitch" ]; then
       empty
   # trash --restore: restore a file to original location
   elif [ "$1" = "--restore" -o "$1" = "-r" ]; then
       RESTORE=1
       shift 1
   # trashy foo: moves foo to trash
   else
       break
   fi
   done

   # 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 proscribed 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, because in effect, if programmers add everything requested
without vetting it through someone with a view of the big picture, 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 it doesn't make
it off the printed page if they were documented and reviewed first.

Documentation, just like coding, isn't a one-time process done early
in an application's life cycle. Your project documentation is a living
document, same as code, contantly updated and revised to reflect both
the development plans of the project and the current state of the
project.

## Consistency

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 week 1 of an
application's development, but then relegate an equally important
function to an obscure right-click menu during week 8 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 a lot different than 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 a 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 myself. 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 then again
some times it's led to the developer learning some new tricks to make
something previously thought out of reach actually work.

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 wersion 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.