I suggest that there are at least five uses for design artifacts and that these uses correspond to stages in a design and development process.
- Design as a thinking aid
The first use of a design is as a thinking aid. Early in the design process, the designer is engaged in the pure creative act (at least that's what I claim when I am discovered staring out of the window). Although the earliest stages may take place solely in the head of the designer, some drawn or written form will normally appear quite soon. As a minimum, I will draw some form of picture just to stare at - it provides a structure on which to hang my thoughts.
With any design of real complexity there will be one or more difficult problems to solve or critical aspects to handle. Exactly what these are depends on the system but common ones include performance, robustness or complex algorithms. While attempting to solve these problems, the designer will want to draw pictures or create state or sequence diagrams to explore them and to test theories. If the problems are suitable then a partial prototype can be very useful.
At this stage, the design artifact should contain only what is needed to investigate the key problems: obvious or easy parts of the design can be taken for granted. There is no need to have a standard form or to cover all aspects of the design and the design does not have to be optimized for communication.
- Design to support Peer Review
The second use of a design is to support a peer review of the design. Actually, I want to include both formal peer reviews and informal design discussions but I will cover the formal reviews first.
In order to support a peer review, the design artifact needs to support communication - the design concept needs to be shared with the reviewers. This is where the use of some standard or shared notation kicks-in to minimize the learning effort.
It is likely that a design for peer review will need to include at least a minimum of standard information to provide context but the emphasis should be on describing the difficult or critical aspects so that they can be thoroughly reviewed.
Of course, there is a hidden gotcha here. If the designer skimps on the detail for the parts that can be taken for granted and is wrong in their judgment then the peer review will miss these problems. This is an argument for covering all aspects of the design to some level of detail but I still believe that more effort should be expended on the aspects that the designer knows are problematical.
Because the purpose is to allow Peer review, this type of design must include more than just static pictures. State diagrams or sequence diagrams should be used to show how the design works or how it can be used.
By separating the design as a thinking aid from the design for peer review I have omitted an intermediate stage, the design as a tool for early design discussions. Wherever possible, I like to get input from other people on a design and this requires something to talk about. If you are lucky, this can be a picture drawn on a whiteboard with minimal effort. If the design is more complex (or at least the part of the design that you want to discuss is more complex) then you may need to create a more formal representation in order to get the other contributor(s) up to speed. Whichever form you choose, this is not a formal peer review so you can focus on the aspects that you want to discuss without filling in the rest. As this type of discussion is cheap to carry out, I recommend them early and often.
- Design to define and communicate structure & interfaces
Any system of more than minimal complexity will need to be split into parts (I avoid using a term such as components because it can have specific meanings in some methodologies) for understanding, implementation and, probably, operation. Exactly what form the decomposition takes depends on the system. A Web services architecture will involve distributed processes, each of which may be further decomposed, while a stand-alone application may be decomposed into classes or DLLs.
The decomposition of the system and the definition of the interfaces is crucial to the design of a system and so a design should describe them. This type of design can then have several uses. It can be used by teams or individuals to implement the parts. It can be used by testers to implement various levels of tests. It can be used by customers of the system as documentation for using it.
Although the decomposition is essentially a static picture of the system, the interfaces will almost certainly benefit from a dynamic description such as sequence diagrams. For those interfaces that will have external customers, I like to have a draft tutorial document at this stage, even before coding starts.
With this type of design, the internal structure of the parts does not need to be described unless they are critical or difficult.
- Design as a work description
I dislike the development process that this type of design implies. I have seen designs created to guide 'less skilled' coders but I would much rather encourage the implementers to create any additional designs that they need where the internal structure or behaviour of components is not obvious and then carry out early and possibly repeated reviews. In this way, the implementers grow in skill and ability and there is no artificial divide between designers and coders.
This approach does require more communication and reviews within the team but I regard that as beneficial.
- Design as a maintenance guide
At this point I have jumped from design artifacts created before or as part of implementation to design artifacts required after implementation. I think that this aspect is often overlooked or misunderstood and I will expand this view below.
If a system is to have a significant lifetime then it will need to be maintained. Any designer who believes that their system will never need maintenance is lying, either to themselves or to others and maintenance can include fixing defects and extending the system for new uses. Given the likely need for maintenance it is sensible to consider what type of documentation will support it.
During maintenance we can assume that we have some other artifacts - at least the code for the system and, with luck, some working test cases. Maintaining design documents after implementation is always problematical; under time pressure, it is always tempting not to bother to update them. Therefore, we should try to keep maintenance support to the useful minimum.
If your code is well documented (hint - Doxygen at least) then you do not need to reproduce detailed API documentation but maintenance documentation should include- an architectural overview
- interface descriptions where in-code comments are not adequate (keep the sequence diagrams)
- records of interesting design decisions (to avoid maintainers inadvertently undoing them)
- guides to expected extensions
The key point overall is not to assume that there is one true form for a design document and it must be created early and then maintained throughout the design process and system lifecycle. Instead, we should consider what the purpose of the design document is at each point in time and set the content accordingly.