about
3/05/2022
Design

Design Bite - Design and Documentation

Concept, Design, Evolution, Document

"There are two ways of constructing a software design; one way is to make it so simple that there are obviously no deficiences, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult."
- C.A.R.Hoare

Prologue:

Definitions for design from Merriam-Webster:
  • .. scheme in which means to an end are laid down
  • .. outline showing the main features of something to be executed
  • a plan or protocol for carrying out or accomplishing something ..
I often work on designs early in the morning, coffee cup in hand - scribbling notes and diagrams on sheets of paper, many, at first, get crumpled and thrown away, but soon there's a small stack of papers, perhaps five or six, convincing that the project is sensible, do-able, and has a clear starting point. Implementing code is a consuming mental task. We think about the context, semantics, and syntax of each line of code we write. That doesn't leave too many mental cycles for building a well structured program that is quick, robust, elegant, and easy to use. That's why project design begins before coding, perhaps at the start of coding sprints, and finally as a post-mortem process to get documentation user-ready.

Program Design Concept:

Concept is the starting point for design. Concept development may precede creation of a specification governing program build. It focuses on users and uses, program structure, and issues. Users and uses considers who the users are and what they need from the program. Exploring this thoughtfully could make the difference between a satisfactory outcome and creation of "shelfware" that no one wants to use. These considerations help to specify program operations. Structure deals with what top level parts are needed to build the program, or system of programs. This doesn't get into a lot of detail, but should identify top-level parts, processing phases, and data flow. Issues lay out all the things we can think of that may affect program function or ease of construction, use, and maintenance.

Design:

The purpose of design is to think about structure and process strategies before diving into coding. We want our designs to:
  • Explain, in brief, unambiguous, and relatively complete fashion, the project goals, structure, processing concepts, and delivered information.
  • Extract away all of the details of platform and language so that our ideas take precedence.
  • Be small and simple enough that team members will acturally read the document.
Try to implement the "Goldilocks principle" - not to much, not to little, just enough to guide your implementation. It is important that the description of a design be pragmatic and concrete. No vague statements like "optimum" or "user-friendly" Those words provide almost no guidance for an implementation. Prefer statements like "program options are supplied with named command line arguments of the form '/P .' to specify that a search path is to start at the current working directory".

Design Evolution:

None of us has perfect foresight. It is not uncommon that a good design evolves a bit as it is implemented. We think of better ways to process some data or decide that the structure needs refactoring to add a part or two that will handle some processing that turned out to be more complex than expected. Evolutionary development is a powerful way to be effective, both for individuals and teams. The agile movement has shown how well that can work - if applied with some wisdom. That means that design will happen repeatedly, once for each evolutionary step. When used in this enviroment, each design phase is relatively small, focused, and results in brief documents. Each phase will probably build on the document from the preceding phase. This reuse has the same benefits as code reuse. The evolutionary process is a good way to manage this extension of design.

Design of a Software Design Document:

A design document represents a program design, providing:
  1. A brief specification, if one doesn't already exist. Ideally:
    • One or two line statement of what the program does
    • Pre-conditions: the program's environment and inputs
    • Post-condtions: a list of things it must provide
    • Non-functional requirements: platform, programming language, ...
  2. Use: how will users interact with the program: what inputs do they supply, how do they interpret program results - the program is, after all, going to supply information, not raw data - right?
  3. A list of tasks the program must execute, more or less in the order they occur during operation. Each task becomes a candidate part in the program's structure. Some will become parts, some may not.
  4. A structure consisting of a network of named parts, where each part has a stated responsibility. Parts might be functions, or classes, or packages.
  5. One or more diagrams showing structural relationships, e.g., a call stack diagram, or class diagram, or package diagram, or some combination.
  6. A description of the major processing parts. If you help your friend work on her motorcycle you might describe in words and a diagram how to clean and adjust the bike's carburetor. You do the same thing here, perhaps briefly describing a directory tree traversal or messaging process. Pseudo-code may work well for this.
  7. A description of error handling. What errors may occur? How will they be handled?
  8. Testing description: test name, description, procedure.
  9. Thoughts about future expansions, not implemented, but which may be in future versions. That could lead us in a design direction that we would not otherwise follow.
  10. Very brief outline of a prototype developed to verify feasibility of one or more operations.
What do you mean small and simple! There's a lot of steps here. Look's like Goldilocks slept in today. Robin Mathew said "Design is where science and art break even". Here is where the art comes in. Speaking and writing in clear, simple, brief statements. If in doubt, throw it out! If a project is small - perhaps a week's work, then a small design is appropriate; just enough to think about processing and use. Some of the steps, above, would be unnecessary. Big projects with several developers working for a month or more will likely address each of the steps described here. "Put it before them briefly so they will read it, clearly so they will appreciate it, picturesquely so they will remember it and, above all, accurately so they will be guided by its light."
- Joseph Pulitzer, Editor

Why Write one:

Should you write a design document for every project you build. No! If the project is relatively small, in a domain in your comfort zone, and similar to things you've built before, writing a design document is probably a waste of time. Write a document when:
  • The project is relatively large or has some complex processing. Write a document to help you think through processing and communication. When the implementation is complete, the document will live on as a maintenance manual.
  • The project has more than one developer. You need to name parts, specify interfaces, data flow, and test processes so that work can be partitioned for the team, everyone knows their obligations, and the means of communication are clear.
  • User interactions with the program are complex or unspecified. You need to define the user interactions, think about how to make them as simple and intuitive as practical, and partition program parts to allow changes to input and output processing without major surgery to the other parts. The document will live on, after program completion, as a user's manual. Here's a user manual for this site, a quite complex design.
Remember: a design document is not some large ediface. It should be small, clear, and readable. Documents for your own use might be two or three sheets of paper. For sharing with others, the document may need more than that, but keep it short and simple - the KISS principle.

Building a Design:

You might scribble ideas on a few pieces of paper, then build your design by writing a design document, thinking and creating as you go. One of the best ways to think clearly about some complex topic is to try to write about it. Expository writing is very similar to developing code. You start with an idea, then describe it, bound by the syntax, context and conventions of your topic. Essentially writing is coding ideas rather than functions and classes. Same issues of connections, process, and structure. Sometimes I have written design documentation after the implementation is complete - providing information for others. I've often regretted not working through the design process first. I've found things I wish I had done differently. Sometimes I am quite dissatisfied with the code structure or its processing mechanisms or its user interface. While that post-mortem is useful, it is also dissapointing to find that you could have built so much better. Implementation may start as part of this process. As packages are identified you can create a package file and state its requirements in its opening comments. For projects with multiple contributors you might think about building your concept, specification, and design documents as web pages, perhaps using markdown. That makes collaboration effective at this early phase of development. That was done for TextFinder in the BuildOn project.

Presenting Designs:

Let's assume you present using slides. Allow 2 minutes per slide (that is optimistic). So a ten minute presentation means you will have 5 slides including your opening and closing slides. Clearly you have to cherry-pick the design document, selecting small pieces of of each design topic as representative of your design. You may have to eliminate some of the design topics altogether. Keep those with the most impact for your audience. Be very careful to stick to the script. Don't ramble, use one strong statement per topic with perhaps a very few words of elaboration. Finally, talk to the audience - don't read your slides. The slides are there for your audience and to keep you on track. Remember, you know more about your presentation topic than the audience.

Epilogue:

We want to make our programs elegant and simple, make their intents clear, and make them quick and reliable. That is most likely to happen if we think first about design.
  Next Prev Pages Sections About Keys