What Makes a Good Design Document?
dnnrly asks: "I've been writing software professionaly for a couple of years now for more than 1 company and I've noticed a recurring pattern: I get put on a new project that already has a bit of history and I get told to read the design documents and then implement XYZ. What happens is I read the document, find that it gives me a lot of information about certain aspects of the system we are building, but leaves huge gaps in others. We're going to be rewriting some of the procedures very soon and I'll be able to influence the software side so I wanted to ask Slashdot readers what sort of things have they seen in design documents that they've liked/thought are a good idea? What have they found works and what doesn't? If all else fails, where's a good place to find all this stuff out?"
"There's usually a very defined and rigid format for every design document and the writers have obviously tried very hard to make sure that procedure has been followed, generally leading to an almost unreadable doc or a design for the sake of it. Part of the issue is that these guys have written the design after 2 or more years exposure to the problem so they tend to forget just how much they know."
Here's the classic article by Jack Reeves.
The Army reading list
The best design documents are ones that aren't trying as much to fit the cookie cutter as much as they clearly convey the idea of the design.
I'm not saying to throw design standards to the wind. I'm saying that your standard as a design document generator is to create something that is readable, decent to look at, and clearly conveys what is going on.
Try to use vernacular vocabulary and language style when explaining what things do, and try to make your pictures look as pleasing and simple as possible.
Hope that helps.
Summary:
This series of articles is about functional specifications, not technical specifications. People get these mixed up. I don't know if there's any standard terminology, but here's what I mean when I use these terms.
- A functional specification describes how a product will work entirely from the user's perspective. It doesn't care how the thing is implemented. It talks about features. It specifies screens, menus, dialogs, and so on.
- A technical specification describes the internal implementation of the program. It talks about data structures, relational database models, choice of programming languages and tools, algorithms, etc.
When you design a product, inside and out, the most important thing is to nail down the user experience. What are the screens, how do they work, what do they do. Later, you worry about how to get from here to there. There's no use arguing about what programming language to use before you've decided what your product is going to do. In this series, I'm only talking about functional specifications."One of his books: Joel on software
His blog: What's a Spec?
Highly recommended!
I have to agree with the statement about traceability though. One of the worst things I've had to deal with is getting a specification document that does some stuff and then have to write the requirements "that would result in this design if we started with those requirements." This is endemic to all industries: ill-formed or ill-stated requirements. I'm always amazed at how many "requirements" are either designs or implementations or are not testable or aren't requirements at all. Even more entertaining are tests that don't test in a way that proves requirements are met...
If I had to enumerate what makes good design the list would have to include:
- DO NOT START DESIGN UNTIL YOU HAVE THE REQUIREMENTS (yes, I know there are exceptions, but you should at least have *most* of the requirements first).
- Have a good requirements document: everything is actually a requirement (not a design or implementation) and is testable (if you have the word "not" in it, it's not testable, for instance).
- Make sure the design is design and not implementation (design is "sum two numbers and check for overflow"; implementation is "temp32 = x16+y16; if temp32 > MAX16 then result16 = MAX16 else result16 = x16+y16;). Put another way, despite the popular writings I've seen lately to the contrary, CODE IS NOT DESIGN (any more than a car is the design of the car).
- Make sure you can test that THE DESIGN MEETS THE REQUIREMENTS (which is subtly different than "does the design do what I designed it to do?"). If the design doesn't satisfy the requirements, it can never be a "good design".
- Separation of responsibility. You mentioned XP above where "the designer is the coder is the tester" which is just bad practice in my experience. My company *strongly* discourages the designer to be the coder, or the coder to be the tester (the designer can be the tester though, and this often makes sense). This is because there are inevitable blinders that you put on when coding your own design or testing your own code.
Ok, that wasn't an exhaustive list by any means, but I think those are the key points. To summarise: have good requirements, separate requirements from design from implementation, and have many eyes looking at things throughout the whole process."There are a dozen opinions on a matter until you know the truth. Then there is only one." - CS Lewis (paraprhase)
Getting back to the original question, a design document should be divided into three primary sections. The first section should always say what the problem is that the design document is trying to address. Any given design document should address only a limited set of problems, or it will become too complex. Ideally, any given document should be small, compact and address one or (at most) two issues.
The second section should describe how to use the solution presented to solve the problem described. In programming terms, this is your API. That is all it should describe.
The third section should then cover how the solution goes about solving the problem. Again, that is all it should cover.
When projects or modules within those projects are updated, it should be possible to update/replace any one section in any one document without touching any other section or any other document.
Documentation should also always stick to the level for which it is intended. Ideally, references should be to ever-more specific information, never the other way round. So, a project overview might point to the components of that project. Each component might then point to documentation on the low-level mechanics. On the other hand, a discussion on low-level mechanics is not the right place to talk about a specific project that uses those mechanics. That gets in the way of understanding and obstructs code reuse.
That, I think, is the key to writing good documentation. Does it positively assist those who would need it? If the answer is "no", or is even a "not sure", then it doesn't matter what standards it follows, it is useless.
The ideal length for a document is going to vary, project to project, but by building documents in a modular fashion it should be rarely necessary to have a document longer than about 20 sides of A4. Most should be around 10 sides. Anything longer likely covers unrelated topics and can be split up. (Remember, it is easier to open 20 books to one page each, than to open one book to 20 different pages.)
This limit gives you about 3-7 sides per section per report. If you need more than 7 sides, the design is too complex and unmaintainable over the long-haul. On the other hand, any less than 3 sides likely means that the project has been over-designed with lots of redundancy, plenty of overhead and no possibility of meeting the requirements.
Going by this description, virtually all documentation in existance is ghastly beyond all imagining. Which, by and large, is exactly how most people see it.
It's a small world and it smells funny; I'd buy another if it wasn't for the money; Take back what I paid (SoM)