The difference between heuristic and deterministic processes is described in Chapter 2, "Metaphors for a Richer Understanding of Software Development."
Design is also
challenges, which are outlined in this section.
Design Is a
Horst Rittel and Melvin Webber defined a "wicked" problem as one that could be clearly defined only by solving it, or by solving part of it (1973). This paradox implies,
, that you have to "solve" the problem once in order to clearly define it and then solve it again to create a solution that works. This process has been motherhood and apple pie in software development for decades (Peters and Tripp 1976).
The picture of the software designer deriving his design in a rational, error-free way from a statement of requirements is quite
. No system has ever been developed in that way, and probably none ever will. Even the small program developments shown in
and papers are
. They have been revised and polished until the author has shown us what he wishes he had done, not what actually did happen.
—David Parnas and Paul Clements
In my part of the world, a dramatic example of such a wicked problem was the design of the original Tacoma Narrows bridge. At the time the bridge was built, the main consideration in designing a bridge was that it be strong enough to support its planned load. In the case of the Tacoma Narrows bridge, wind created an unexpected, side-to-side
ripple. One blustery day in 1940, the ripple grew uncontrollably until the bridge
, as shown in Figure 5-1.
Figure 5-1. The Tacoma Narrows bridge—an example of a wicked problem
This is a good example of a wicked problem because, until the bridge collapsed, its
didn't know that aerodynamics needed to be
to such an extent. Only by building the bridge (solving the problem) could they learn about the additional consideration in the problem that allowed them to build another bridge that still stands.
One of the main differences between programs you develop in school and those you develop as a professional is that the design problems
by school programs are rarely, if ever, wicked. Programming assignments in school are devised to move you in a beeline from beginning to end. You'd probably want to tar and feather a teacher who gave you a programming assignment, then changed the assignment as soon as you finished the design, and then changed it again just as you were about to
in the completed program. But that very process is an everyday reality in professional programming.
Design Is a
Process (Even If it Produces a Tidy Result)
The finished software design should look well organized and clean, but the process used to develop the design isn't nearly as tidy as the end result.
Design is sloppy because you take many false steps and go down many blind alleys— you make a lot of mistakes. Indeed, making mistakes is the point of design—it's cheaper to make mistakes and correct designs than it would be to make the same mistakes, recognize them after coding, and have to correct full-blown code. Design is sloppy because a good solution is often only subtly different from a poor one.
exploration of this viewpoint, see "A Rational Design Process: How and Why to Fake It" (Parnas and Clements 1986).
Design is also sloppy because it's hard to know when your design is "good enough." How much detail is enough? How much design should be done with a formal design notation, and how much should be left to be done at the keyboard? When are you done? Since design is open-ended, the most common answer to that question is "When you're out of time."
For a better answer to this question, see "How Much Design is Enough?" in Section 5.4 later in this chapter.
Design Is About Tradeoffs and Priorities
In an ideal world, every system could run instantly,
zero storage space, use zero network bandwidth, never contain any errors, and cost nothing to build. In the real world, a key part of the designer's job is to weigh competing design characteristics and strike a balance among those characteristics. If a fast response rate is more important than minimizing development time, a designer will choose one design. If minimizing development time is more important, a good designer will craft a different design.
Design Involves Restrictions
The point of design is partly to create possibilities and partly to
. If people had infinite time, resources, and space to build physical structures, you would see incredible sprawling buildings with one room for each shoe and hundreds of rooms. This is how software can turn out without deliberately imposed restrictions. The constraints of limited resources for constructing
of the solution that ultimately improve the solution. The goal in software design is the same.
Design Is Nondeterministic
If you send three people away to design the same program, they can easily return with three vastly different designs, each of which could be
acceptable. There might be more than one way to skin a cat, but there are usually dozens of ways to design a computer program.
Design Is a Heuristic Process
Because design is nondeterministic, design techniques tend to be heuristics—"rules of thumb" or "things to try that sometimes work"—rather than repeatable processes that are
to produce predictable results. Design involves trial and error. A design tool or technique that worked well on one job or on one aspect of a job might not work as well on the
project. No tool is right for everything.
Design Is Emergent
A tidy way of summarizing these attributes of design is to say that design is "emergent." Designs don't spring fully
directly from someone's brain. They
and improve through design reviews, informal discussions, experience writing the code itself, and experience revising the code.
Virtually all systems undergo some degree of design changes during their initial development, and then they typically change to a greater extent as they're extended into later versions. The degree to which change is beneficial or acceptable depends on the nature of the software being built.
Software isn't the only kind of structure that changes over time. Physical structures evolve, too—see
How Buildings Learn