On Design and Design Documents

Norman Ramsey
Fall 2008

Introduction

Engineering is design under constraint. Sometimes a constraint is imposed from outside (data must fit on the computer's hard drive) and sometimes a constraint embodies what we want from a system (I want a backup server that draws at most 10 watts of power, so I can leave it on all the time.)

In computer systems, design means breaking a system into pieces which cooperate to produce a harmonious, useful whole. For the software parts of a design, the best tool we have for understanding what a piece is and how it cooperates with other pieces is the interface.

When I give a programming assignment, I often ask for a design document. A design document is one of many ways to describe software, and software engineers have a huge vocabulary for talking about descriptions. I don't worry about the vocabulary, but an analogy with homebuilding might be helpful. If I want a 4-bedroom Colonial, that might be called a requirement; if I know how many square feet and of what materials, that might be part of the specification; brief descriptions of plan and elevation might constitute a design; blueprints or architectural drawings might be detailed design, and of course the house itself is the implementation.

In class, I ask for a design document to increase your chances of producing a correct and complete implementation without pain. Writing a design document develops your ability to think about your design, and such thought will reduce the number of costly and unplanned changes to your software program (i.e., late nights). The design document helps you think before you code.

Alert!

Design documents are due well before implementations. Take proper advantage of this structure: start thinking about how to design your program before you start writing it. Think first, code later, finish early, and enjoy life.

Contents of a Design Document

To help your reader (and yourself) focus on whatever part of your design may be relevant at any given time, I ask that you break down your design document into clearly labelled sections. You'll want to write these sections (in the order in which they appear):

Advice on your implementation plan

The key to successful implementation is to get an end-to-end solution working as quickly as possible. You want a program that does something which you can work with and then improve. Programming is easier and more fun when your code always does something.

Something trivial is a good place to start. For example, if your ultimate goal is to read a bitmap, remove black edges, and write a modified bitmap, you might have a plan like this:

  1. Read a bitmap and write the same bitmap on standard output, without ever putting a pixel into a data structure. Make a quick check for correctness using an image viewer (15 minutes).
  2. Read a bitmap into a two-dimensional array of bits, then write the bitmap to standard output in PBM format (30 minutes).
  3. Perform a trivial transformation on the bitmap, like changing every black pixel to white and every white pixel to black. Check in image viewer (10 minutes).
  4. Identify black edge pixels and make them white (30 minutes).

After the design document

Once you've finished your design, start with your implementation plan. As you proceed, you may find use cases, requirements, and corner cases that you did not anticipate. In response, your design might change. It's all good—my goal is to have you think about design decisions; you won't usually need to update your design document to reflect new decisions. If I ever want an updated design document, I'll let you know.

When you have difficulty

Both design and programming will challenge your intellect and ingenuity. Don't let anybody kid you that it's easy, [Part of the culture of computer science is that when working engineers are collaborating on a design, someone may say, ``from this point on it's just a Simple Matter of Programming.'' The secret passphrase is uttered by one programmer to another when both parties know well that almost nothing about programming is simple. Properly translated, the statement means ``well, we've done a lot of preliminary work, and things look good enough that now we can get started on the hard stuff.''] and if you don't know how to get started, don't get discouraged. One benefit of the design document is it's a cheap way of discovering that you're confused. Take whatever you've written and bring it to a member of your course staff. Everybody on the staff likes teaching, and we'll do our best to ask you questions that will get you on track. Eventually you'll learn to ask yourself helpful questions!

Frequently asked questions

Why do I have to write a design document? Computer scientists need an education in design as well as programming. Design is one of the most interesting, challenging, and fun things computer scientists get to do. When you graduate, I want you never to be stuck in a situation where other people have the fun of designing the programs you write.

How long and how much detail should be in my design document? Regarding detail, focus on the architecture, especially its novel features. Detailed code is usually out of place: the design document focuses on the interaction of components, not the implementation of each component. Your implementation plan should include more detail than just what components will be written in what order. When will you write which components? How long will they take? How will you test your system when it is still small and manageable, but incomplete? Regarding length, provided you give the information needed, shorter is always better. Overall, your design document should embody a clear, concise, and simple specification for the implementation you plan.

An obsessive-compulsive design document

Here's an acceptable design document. This one is over the top; there's much more detail than necessary. The extra detail is there to give you ideas about how to make an implementation plan in a way that gives you an end-to-end system as soon as possible—and that lets you test as you go.

Commentary on the design: Goldilocks and the missing memory

There are two ways in which the design document above is not a model to follow. One simply a mistake commonly made by C programmers. The other, which is more imporant, I'll call the ``Goldilocks effect;'' it's a problem common to almost all programming methodologies taught in universities.

Acknowledgment

This document is adapted from a document written by terrific teaching assistants who worked for Radhika Nagpal and Margo Seltzer; I'm sorry I cannot acknowledge them by name. Thanks to Radhika for permission to adapt it. Any errors or infelicities are my own.