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."
Figure out which class from your local university deals with software engineering, find the book(s) for the class, and buy it.
Writing a good design doc is mostly tedious work interspersed with lots and lots of communication with your programmers and customer.
-Erwos
Plausible conjecture should not be misrepresented as proof positive.
Be sure your DD includes:
- Sitemap (web) or screen map (desktop app)
- Feature matrix with columns for features, rows for pages/screens and indicators where a page/screen has a feature.
- Detailed feature specs need to be written kinda like function documentation - "preconditions" that state what is expected as in the user is authenticated or the DB has products and "post conditions" that say what gets set or hwat the user can do.
- Style documents greated by graphics designers who understand the medium (web/Windows API/etc) are invaluable for refering back to when someone doesn't like a font size.
All this documenting is no fun, but it is more fun then dealing with the lake of the document.
I only came here to do two things; kick some ass, and drink some beer...looks like we're almost out of beer.
I document software for end users, and get some of my information in the early stages of development from design docs. I have to say that the most useful design documents that I've seen are ones that contain diagrams, flowcharts, and other "pictures" of how the system (or the module, component, whatnot) functions.
If I have to choose between a 50-page design document and three pages of clear diagrams, I'd pick the pictures.
Interested in a Flash-based MAME front end? Visit mame.danzbb.com
The net will not be what we demand, but what we make it. Build it well.
. . . is a prototype.
To be honest, I find that customers have a hard time visualizing how something will work unless they can interact with it. I'll take some internal design notes for myself, then whip up something and reiterate.
This approach doesn't work well with some projects, but for the small web applications I make it works great.
Existence.
At least for most of the projects I've worked on.
... the "this is how it really works" document. That's what you're really interested in. There's nothing wrong with the design documents you've seen.
No, I'm not kidding.
The design documents which have driven you mad probably weren't incomplete. They were probably quite complete design documents. But a complete design document isn't supposed to cover everything. If you had a design document that was fully specified in every significant detail, you could run the design document through a compiler and generate your code. (This isn't as far-fetched as it sounds; there are tools to automatically generate large amounts of code just from simple UML diagrams. That's an example of design documents being translated directly into running code.)
A design document can best be viewed as the development team's prejudices regarding the best way to solve the problem. There will be holes in the design document, mostly in those areas where the programming team doesn't really have a good grasp on what the best thing to do is.
A good design document is a like a good steak; they're best when served a little bit rare. You want to give the guy who comes after you a game plan, but you don't want to commit yourself to doing things in one particular way when you don't know if that one particular way is going to work. After all, once the design document has had every stakeholder sign off on it, going back to the drawing board and saying "uh, this isn't going to work, let's try something else" means all the stakeholders get back on board again. But if the design document has some room to move--what you think are "holes"--then that gives the programmers freedom to get the job done without having to go through the entire design approval bureaucracy again.
Most serious software engineering shops worship at the altar of requirements and architecture documents. Hackers in the trenches add the "this is how it really works" document to that list. There's nothing quite as valuable as stumbling across some prior hacker's notes when you're trying to grok the system.
Stop looking at the design document for the 'missing' stuff. It might very well have been deliberately omitted. Start asking around for the "this is how it really works" documentation, instead.
Much of software engineering is received wisdom. It involves little engineering and even less science.
I draw the analogy to medicine in the 19th century because at that time physicians were finally trying to investigate the causes of disease and developing insight that, more than a century later, would lead to their interventions improving rather than diminishing life expectency.
Nobody knows what "best practice" should be, yet we're codifying a process. The design document is one aspect of this process. Rarely is the purpose of a design document to convey design. Rather, it is a "deliverable" presented to a PHB or client as evidence of progress. To this end, the larger and prettier it is, the better.
Design Docs tell the reader how you intend to build something. In many shops (depending on the SDLC version, if any, that they use), it has little value after the design review.
As a roving consultant, I've seen a lot of crappy documents and SDLC (et.al.) procedures, and what has the greatest value for the programmers who come later is a Maintenance document that specifies:
1. The overall philosophy of the design: Why specific design choices were made.
2. What things did you want to implement (and why) but were postponed to a later version.
3. What design decisions were specifically rejected (and the reason).
4. Where are the system's weaknesses?
5. What are the coding standards specific to this particular project?
The Maintenance Doc provides guidance to the people who have to work on this stuff after you're gone (and to you, unless your memory is perfect). More than anything else, they will need to know the why of the design, not the what.
In my perfect world, the maintenance doc would be the main appendix to the design doc.
However, in most shops, the SDLC & its policies & procedures will prohibit that, and usually acknowledge neither the existance nor desirability of a Software Maintenance Document.
Good Luck.
There is not nearly enough love in the world, but there is far too much trust.
The five steps enumerated here are, sadly, rather untenable. In particular, points one and two make a fundamental assumption that I believe is invalid - get your requirements first. If we have learned nothing in the past 40 years of software, and especially in the last decade, it's that we will never have "the requirements." We will have subsets, or views of the requirements, true. The fact, however, is that requirements change during the life of the product development.
Skipping to point four for a moment: I would argue that the requirements should be expressed in the form of tests - functional, unit, or otherwise, and that these tests be executable. The design MUST therefore meet the requirements. This then means that point number three may or may not apply.
I agree that code is not design. Design is abstract, and code is not. And pure-code-no-design folks go overboard in my view, but if you can't have complete requirements (and you can't) then you certainly should document that which is not obvious from a structural breakdown of the code itself. Particularly, documenting risky or unusual features of the code, such as tortured relationships and their semanitcs. To me that is the limit. Document what is not obvious, do not document what is structurally implicit, or otherwise explicit. Documentation covers risk, and risk mitigation points (ie. person hours) are best spent making better software, except when documenting something that, if left unsaid, might lead other developers to an incorrect assumption or conclusion.
As to point number five, your experience may vary. In my experience, it's quite the reverse. But in the example I'm thinking about, we didn't have each individual designing - the whole team designed together, and the whole team coded and tested, and never alone. Also, design changes, or any changes to assumptions (or APIs, or etc.) were well published throughout the team, so that there was ongoing restatement of context. If anyone thought that something was an odd or interesting design feature/artifact, they mentioned it, and the author clarified it and documented it. I don't think having individuals altering design outside of a process of consultation is wise, and I think this "cowboy" flavour of agile developent is abortive and a throwback to no-process development. However, small teams that are engaged collectively produce, in my experience, excellent design. You then need to capture what is not obvious, or somewhat obfuscated, and especially capture assumptions.
Where ThosLives and I would agree, however, I think, is that you need to trace design aspects to requirements. You may not have final requirements, but you always have some, and you shoulnt' make design decisions without a requirement to trace to. In this sense, you absolutely must have tracability from requirement to design to implementation to proof (test). And if requirement can be expressed as a test (not all requirements can), then that is, in my view, the best way.
i - This sig provided by
When I use the blueprints for an automobile to build the automobile, I get something different than the blueprints. I cannot use the blueprints to emulate the functionality of the vehicle. The blueprints are instructions to build the vehicle.
In software, the design is the thing which tells me how to write the code (have you ever tried to read code and find out what the function is supposed to do? generally you can only know what it does, not what it's supposed to do. Sometimes you get lucky and the design is written in the comments, but that's rare; generally comments just say "we watch out for overflow here" or something like "use pointer rather than array lookup to avoud some tricky thing" - comments are usually descriptive of what is going on, not why). If I have a good design I can write it in any language and meet the same requirements. That's a good litmus test for software: if it depends on a language, it's not a pure design. If you have to figure out what's going on to translate into another language, you're in implementation rather than design.
I will grant, however, that there are some difficult situations when you have a requirement "you shall use language X for this project", or "we decided to use language X to meet these requirements" - what happens if that requirement changes halfway through and your "design" was language specific? You're hosed. Good designs are language transparent.
Remember, the goal isn't to produce an application, the goal is to meet the requirements. The design tells you how you are going to meet the requirements ("have a text grid input box" and, at the next level, "have a function that draws a text grid input box") and the code fulfills the design ("textgrid.draw()"). (Note that some design decisions become requirements for a lower level, such as function calls, interfaces, etc.). Code should only be implementation.
"There are a dozen opinions on a matter until you know the truth. Then there is only one." - CS Lewis (paraprhase)