I read that at Google, engineers create a design document for just about every project they work on. It led me to think about how I might incorporate design documents into my usual work practices. I’m looking for processes for teams of one or a few people. Here’s what I hope to get out of a design document:
- Describe the requirements for the feature (or set of features) described by the design document.
- Enable the writer to clarify their own thinking on the design of the feature being described.
- Enable the person who’s requested the feature to be able to review the design to make sure their requirements are being met.
- Enable other developers to review the design document to find flaws and suggest improvements.
- Enable anybody who’s going to be working on the product a year down the road to review the design document and figure out what the code they’re working on is actually supposed to do.
So what goes into a design document and how do you structure it? For a bit of guidance, I looked at the types of UML diagrams that are available. I’m not a huge fan of UML, but the theory behind it is that a full suite of diagrams models a system in its entirety. Here’s how I rate the various diagrams in terms of their conceptual utility. There may be better ways to represent the concepts in the diagrams that UML.
|Class diagram||Describes the objects in an object-oriented system and their relationships to one another. Indispensable.|
|Component diagram||Basically a higher level class diagram|
|Composite structure diagram||Not even the guy who documented it found it useful|
|Deployment diagram||Describes the actual deployment environment for an application. Useful if you are speccing out deployment (or recommended deployment).|
|Object diagram||Basically a class diagram with actual data filled in. A fancy word for “example”.|
|Package diagram||Shows the components of a system at a higher level than the class diagram. Utility is marginal at best.|
|Use case diagram||I’m not in love with these diagrams, but the concept behind them is essential to design.|
|Activity diagram||Some call it a flow chart. It’s hard to describe any complex design without something along these lines.|
|State Machine diagram||More specific than an activity diagram, which is more specific than a use case diagram. Useful when you’re modeling something too complex to be captured in the activity diagram.|
|Sequence diagram||Shows how messages are passed within a system. Only useful if generated from code. Too granular otherwise.|
|Communication diagram||Describes relationships between objects in a system in terms of the messages they pass. Again, very granular, but a nice thing to have if you can generate it.|
I don’t want to dig too deeply into UML, but I did want to bring it up because it’s somebody’s idea of how to describe a system. It’s important to remember that the ideal use case for UML is in a system where the diagrams are coupled with the code itself, so altering your code updates the diagrams and vice versa. No programmer has enough time to create all of those diagrams by hand and keep the diagrams in sync with code as the system evolves over time. That’s not how UML is used, ideally. Unfortunately, the UML tools that are out there have never been compelling enough to me to bother with them.
The Wikipedia Definition
Wikipedia’s page on design documents is short and nominated for deletion. It lists four sections for such a document:
- Data design
- Architecture design
- Interface design
- Procedural design
I don’t think that’s quite right either because it leaves out use cases, which are necessary if you are serious about user experience. If you don’t how who’s going to use your application and what they hope to accomplish, you’re never going to get the interface right. So here’s a stab at what I think a design document ought to contain.
A Rough Draft
So here are the elements that I think should appear in a design document, even for a relatively small project. I don’t care whether they are diagrams or narrative. Some things are better described in pictures, but at the same time, some of us are better writers than illustrators.
What’s the value? Persuade the reader that the feature is worth implementing in the first place. What’s the purpose? Why are you writing it instead of using something that already exists?
Use case analysis. Who will be using this feature and why? If you’re writing a library, the users will be developers who incorporate it into their own code. If you’re writing a Web application, the user may be a customer who wants to buy something, or a back office employee who’s fulfilling an order, or a writer who’s trying to publish an article. Will this application be used by the same people on a daily basis or will it be used only occasionally by a large group of people? How knowledgeable are these users? UML provides a use case diagram, but this is probably a section I’d prefer to write out.
How is it supposed to work? A high level technical overview of how the feature will be implemented. I’m not looking for extreme detail here, just a high level overview of how the feature will work in a technical sense. Are you writing this in Java, PHP, or Ruby on Rails? Will you be using a relational database or flat files for data storage? Are you going to integrate the components via a Web service or are they parts of a single application? If it’s a Web application, will you be using an MVC framework? Will you be using a library to handle the persistence layer? The purpose of this section is to give an idea of the scope of the project and what the risks are in terms of completing it successfully. I can also use it to figure out which members of the team might be able to apply their expertise to this problem.
What are the dependencies? You can figure out some of the dependencies from the technical overview, but this section makes the dependencies explicit. Is this project going to introduce a dependency that we can’t rely on in the future? Are we about to build something that the infrastructure people aren’t comfortable deploying? Does anyone in the office know anything about the tools you’ve chosen to implement this feature?
What will be affected? Closely related to the dependency question, this seeks to help everyone figure out what impact this feature will have. Are we going to need to add more RAM to the database server? Is it going to increase our bandwidth requirements? Does it make our reports obsolete? This is one of those questions with no authoritative answer, but the developer should try to anticipate the impact of the feature they want to implement.
Class diagram. If you’re not building an object-oriented system, then an entity-relationship diagram may make more sense. Either way, this diagram describes the structure of your system at a low level. It documents which classes you need to create, how they are represented in the database, and the relationships between them.
How does that sound for a first draft for a design document? What would you add? I expect to revisit this topic soon.