6.170 / Fall 2000 / Documenting a Software System

Handout H10

Objective

A poorly documented system is not worth much, however well it once worked. For small, unimportant programs that are only used for a short period of time, a few comments in the code may be enough. But for most other programs, if the only documentation is the code itself, the program rapidly becomes obsolete. Without good documentation, a program is unmaintainable. A surprise to most novices is that a small amount of effort on documentation is rewarded even within the confines of a small project. Unless you are infallible, you will find yourself returning to code that you have already written, and will question decisions you made earlier in the development. If you don't document your decisions, you'll find yourself repeating the same mistakes or puzzling out what you once could have easily described. Lack of documentation can not only create extra work; it also tends to damage the quality of the code. If you don't have a clear characterization of the problem, for example, you're unlikely to develop a clean solution.

Learning how to document software is hard, and requires mature engineering judgment. Documenting too little is a common mistake. But the other extreme can be just as bad; if you document too much, the documentation will be overwhelming to a reader, and a burden to maintain. It's vital to document the right things. Novices are often tempted to focus their efforts on the easy issues, since these are easier to document. But that's a waste of time, of course; you don't learn anything from the effort, and you end up with useless documentation. Novices also tend to be reluctant to document problems. This is short-sighted: if you know that some aspect of your design is not quite right, or that some part of the problem has not been clarified, or that some code is likely to be buggy, then say so! You'll spare the reader time puzzling over something that appears to be wrong, you'll remember where to look yourself if you run into problems, and you'll end up with a more honest and useful document.

Another issue is when to document. Although it sometimes makes sense to postpone documentation while performing experiments, experienced developers tend to document systematically even temporary code, initial problem analyses, and draft designs. They find that this makes experimentation more productive. And since they've established habits of documentation, it feels natural to document as they go along.

This handout gives you guidelines on how to document your 6170 project. It gives an outline structure and some required elements, but it leaves in the details much leeway for your own judgment. It is crucial that you don't treat documentation as a dull, rote affair; if you do, your documentation will be useless (and painful to produce). So document consciously: asking yourself as you do it why you're doing it, and whether you're spending your time most effectively. 

You should feel free to cut and paste text from any handouts we have given you into your documentation. In particular, you may want to use parts of the problem set handout in describing the requirements. Make sure to indicate clearly, however, any changes you make, so that your TA will not need to emulate Unix diff by hand!

Outline

Your document should have the following structure. Rough sizes in pages (pp) for a typical 6170 project.

(1) Requirements

  1. Overview (0.2 - 1pp). An explanation of the purpose of the system and the functionality it provides. 
  2. User Manual (1-5pp). A detailed description of how the system is to be used; what operations the user can perform; command line arguments; etc. Detailed specifications of formats should be relegated to the Appendix. Any environmental assumptions should be made explicit here: for example, that the program only runs on certain platforms, or assumes a certain directory hierarchy is present, or assumes certain other applications are present, etc. Along with the overview, this manual should provide all the information needed by a user of the system.
  3. Performance (0.5-1pp). What resources the system requires for normal operation, and what space and time it should be expected to consume.
  4. Problem Analysis (2-10pp). A clear description of the underlying problem. Should include one or more problem object models, definitions of their sets and relations, and a discussion of tricky issues. Object models should include both diagrams and any essential textual constraints. Alternatives considered but rejected, with reasons; unresolved issues, or aspects not fully clarified to be resolved later.

(2) Design

  1. Overview (0.5-3pp). An overview of the design. Top-level organization; where the design 'hotspots' are; use of  libraries and other 3rd party modules; pointers to any aspects that are unsettled or most likely to change. Problems with the design: decisions that may turn out to be wrong; tradeoffs between flexibility and performance, for example, that may turn out to be ill-judged.
  2. Runtime Structure (1-5pp). A description of the state structure of the running program, expressed as a code object model. This model should hide the representations of abstract data types; its purpose is to show the relationships amongst objects. Object models should include both diagrams and any essential textual constraints. Representations of data types should be explained (along with their rep invariants and abstraction functions) if those representations are unusual, particularly complex, or crucial to the overall design. Note that abstraction functions and rep invariants should still appear in their natural place in the code itself. 
  3. Module Structure (1-5pp). A description of the syntactic structure of the program text, expressed as a module dependency diagram. Should include package structure and should show Java interfaces as well as classes. It is not necessary to show dependences on individual Java API classes. Explain why the particular syntactic structure was chosen (e.g., introduction of interfaces for decoupling -- what they decouple and why), and how particular design patterns were used. 

(3) Testing

  1. Strategy (0.1-2pp). An explanation of the overall strategy for testing. Black box or glass box; top down or bottom up; kinds of test bed used; sources of test data.
  2. Test results (0.5-2pp). Summary of what testing has been accomplished, and what if any remains; which modules have been tested, and how thoroughly. Degree of confidence in the code: what kinds of fault have been eliminated? what kinds might remain?

(4) Reflection

  1. Evaluation (0.5-1pp). What you regarded as the successes and failures of the development: unresolved design problems, performance problems, etc.
  2. Lessons (0.2-1pp). What lessons you learned from the experience; how you might do it differently a second time round; how the faults of the design and implementation may be corrected.

(5) Appendix

  1. Module Specifications .You should extract the specifications from your code and present them separately here. If you write your comments in the style accepted by Javadoc with the 6170 doclet, you'll be able to generate the specification documents automatically from the code. The specification of an abstract type should include its overview, specification fields, and abstract invariants (specification constraints). The abstraction function and rep invariant are not part of a type's specification.
  2. Test cases. Ideally your testbed generates tests from a file of testcases in a format that is convenient to read and write. You need not include all test cases; in stress testing, for example, you might just note the size of a random input generated. Indicate for each group of tests what they are for (e.g., "stress tests, huge inputs", "partition tests, all combinations of +/-/0 for integer args").
  3. Formats. A description of all formats assumed or guaranteed by the program, whether for file I/O, command line arguments, user dialogs, message formats for network communications, etc.

Documenting Code


Back to the Handouts page.
For problems or questions regarding this page, contact: 6.170-webmaster@mit.edu