· 7 years ago · Feb 19, 2019, 12:14 PM
1Part I
2Laying the Foundation
3In this part:
4Chapter 1: Welcome to Software Construction . . . . . . . . . . . . . . . . . . . . . . .3
5Chapter 2: Metaphors for a Richer Understanding of
6Software Development . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9
7Chapter 3: Measure Twice, Cut Once: Upstream Prerequisites . . . . . . . . .23
8Chapter 4: Key Construction Decisions . . . . . . . . . . . . . . . . . . . . . . . . . . . . .61
9
103
11Chapter 1
12Welcome to Software
13Construction
14cc2e.com/0178 Contents
15â– 1.1 What Is Software Construction?: page 3
16â– 1.2 Why Is Software Construction Important?: page 6
17â– 1.3 How to Read This Book: page 8
18Related Topics
19â– Who should read this book: Preface
20â– Benefits of reading the book: Preface
21â– Why the book was written: Preface
22You know what “construction†means when it’s used outside software development.
23“Construction†is the work “construction workers†do when they build a house, a
24school, or a skyscraper. When you were younger, you built things out of “construction
25paper.†In common usage, “construction†refers to the process of building. The construction
26process might include some aspects of planning, designing, and checking
27your work, but mostly “construction†refers to the hands-on part of creating something.
281.1 What Is Software Construction?
29Developing computer software can be a complicated process, and in the last 25 years,
30researchers have identified numerous distinct activities that go into software development.
31They include
32â– Problem definition
33â– Requirements development
34â– Construction planning
35â– Software architecture, or high-level design
36â– Detailed design
37â– Coding and debugging
38â– Unit testing
394 Chapter 1: Welcome to Software Construction
40â– Integration testing
41â– Integration
42â– System testing
43â– Corrective maintenance
44If you’ve worked on informal projects, you might think that this list represents a lot of
45red tape. If you’ve worked on projects that are too formal, you know that this list represents
46a lot of red tape! It’s hard to strike a balance between too little and too much
47formality, and that’s discussed later in the book.
48If you’ve taught yourself to program or worked mainly on informal projects, you might
49not have made distinctions among the many activities that go into creating a software
50product. Mentally, you might have grouped all of these activities together as “programming.â€
51If you work on informal projects, the main activity you think of when you think
52about creating software is probably the activity the researchers refer to as “construction.â€
53This intuitive notion of “construction†is fairly accurate, but it suffers from a lack of
54perspective. Putting construction in its context with other activities helps keep the
55focus on the right tasks during construction and appropriately emphasizes important
56nonconstruction activities. Figure 1-1 illustrates construction’s place related to other
57software-development activities.
58Figure 1-1 Construction activities are shown inside the gray circle. Construction focuses on
59coding and debugging but also includes detailed design, unit testing, integration testing,
60and other activities.
61Problem
62Definition
63Requirements
64Development
65Software
66Architecture
67System
68Testing
69Detailed
70Design
71Coding and
72Construction Debugging
73Planning
74Integration
75Corrective
76Maintenance
77Unit
78Testing
79Integration
80Testing
811.1 What Is Software Construction? 5
82As the figure indicates, construction is mostly coding and debugging but also involves
83detailed design, construction planning, unit testing, integration, integration testing,
84and other activities. If this were a book about all aspects of software development, it
85would feature nicely balanced discussions of all activities in the development process.
86Because this is a handbook of construction techniques, however, it places a lopsided
87emphasis on construction and only touches on related topics. If this book were a dog,
88it would nuzzle up to construction, wag its tail at design and testing, and bark at the
89other development activities.
90Construction is also sometimes known as “coding†or “programming.†“Coding†isn’t
91really the best word because it implies the mechanical translation of a preexisting
92design into a computer language; construction is not at all mechanical and involves
93substantial creativity and judgment. Throughout the book, I use “programming†interchangeably
94with “construction.â€
95In contrast to Figure 1-1’s flat-earth view of software development, Figure 1-2 shows
96the round-earth perspective of this book.
97Figure 1-2 This book focuses on coding and debugging, detailed design, construction
98planning, unit testing, integration, integration testing, and other activities in roughly these
99proportions.
100Figure 1-1 and Figure 1-2 are high-level views of construction activities, but what
101about the details? Here are some of the specific tasks involved in construction:
102â– Verifying that the groundwork has been laid so that construction can proceed
103successfully
104â– Determining how your code will be tested
105KEY POINT
106Detailed
107Design
108Integration
109Unit
110Testing
111Integration
112Testing
113Requirements
114Development
115Problem
116Definition
117Software
118Architecture
119System
120Testing
121Corrective
122Maintenance
123Construction
124Planning
125Coding and
126Debugging
1276 Chapter 1: Welcome to Software Construction
128â– Designing and writing classes and routines
129â– Creating and naming variables and named constants
130â– Selecting control structures and organizing blocks of statements
131â– Unit testing, integration testing, and debugging your own code
132■Reviewing other team members’ low-level designs and code and having them
133review yours
134â– Polishing code by carefully formatting and commenting it
135â– Integrating software components that were created separately
136â– Tuning code to make it faster and use fewer resources
137For an even fuller list of construction activities, look through the chapter titles in the
138table of contents.
139With so many activities at work in construction, you might say, “OK, Jack, what activities
140are not part of construction?†That’s a fair question. Important nonconstruction
141activities include management, requirements development, software architecture,
142user-interface design, system testing, and maintenance. Each of these activities affects
143the ultimate success of a project as much as construction—at least the success of any
144project that calls for more than one or two people and lasts longer than a few weeks.
145You can find good books on each activity; many are listed in the “Additional
146Resources†sections throughout the book and in Chapter 35, “Where to Find More
147Information,†at the end of the book.
1481.2 Why Is Software Construction Important?
149Since you’re reading this book, you probably agree that improving software quality
150and developer productivity is important. Many of today’s most exciting projects use
151software extensively. The Internet, movie special effects, medical life-support systems,
152space programs, aeronautics, high-speed financial analysis, and scientific research are
153a few examples. These projects and more conventional projects can all benefit from
154improved practices because many of the fundamentals are the same.
155If you agree that improving software development is important in general, the question
156for you as a reader of this book becomes, Why is construction an important focus?
1571.2 Why Is Software Construction Important? 7
158Here’s why:
159Cross-Reference For details
160on the relationship between
161project size and the percentage
162of time consumed by
163construction, see “Activity
164Proportions and Size†in Section
16527.5.
166Construction is a large part of software development Depending on the size of the
167project, construction typically takes 30 to 80 percent of the total time spent on a
168project. Anything that takes up that much project time is bound to affect the success
169of the project.
170Construction is the central activity in software development Requirements and
171architecture are done before construction so that you can do construction effectively.
172System testing (in the strict sense of independent testing) is done after construction
173to verify that construction has been done correctly. Construction is at the center of the
174software-development process.
175Cross-Reference For data on
176variations among programmers,
177see “Individual Variationâ€
178in Section 28.5.
179With a focus on construction, the individual programmer’s productivity can improve
180enormously A classic study by Sackman, Erikson, and Grant showed that the productivity
181of individual programmers varied by a factor of 10 to 20 during construction
182(1968). Since their study, their results have been confirmed by numerous other studies
183(Curtis 1981, Mills 1983, Curtis et al. 1986, Card 1987, Valett and McGarry 1989,
184DeMarco and Lister 1999, Boehm et al. 2000). This book helps all programmers learn
185techniques that are already used by the best programmers.
186Construction’s product, the source code, is often the only accurate description of the
187software In many projects, the only documentation available to programmers is the
188code itself. Requirements specifications and design documents can go out of date, but
189the source code is always up to date. Consequently, it’s imperative that the source
190code be of the highest possible quality. Consistent application of techniques for
191source-code improvement makes the difference between a Rube Goldberg contraption
192and a detailed, correct, and therefore informative program. Such techniques are most
193effectively applied during construction.
194Construction is the only activity that’s guaranteed to be done The ideal software
195project goes through careful requirements development and architectural design
196before construction begins. The ideal project undergoes comprehensive, statistically
197controlled system testing after construction. Imperfect, real-world projects, however,
198often skip requirements and design to jump into construction. They drop testing
199because they have too many errors to fix and they’ve run out of time. But no matter
200how rushed or poorly planned a project is, you can’t drop construction; it’s where the
201rubber meets the road. Improving construction is thus a way of improving any software-
202development effort, no matter how abbreviated.
203KEY POINT
2048 Chapter 1: Welcome to Software Construction
2051.3 How to Read This Book
206This book is designed to be read either cover to cover or by topic. If you like to read
207books cover to cover, you might simply dive into Chapter 2, “Metaphors for a Richer
208Understanding of Software Development.†If you want to get to specific programming
209tips, you might begin with Chapter 6, “Working Classes,†and then follow the cross references
210to other topics you find interesting. If you’re not sure whether any of this applies
211to you, begin with Section 3.2, “Determine the Kind of Software You’re Working On.â€
212Key Points
213â– Software construction is the central activity in software development; construction
214is the only activity that’s guaranteed to happen on every project.
215â– The main activities in construction are detailed design, coding, debugging, integration,
216and developer testing (unit testing and integration testing).
217â– Other common terms for construction are “coding†and “programming.â€
218â– The quality of the construction substantially affects the quality of the software.
219â– In the final analysis, your understanding of how to do construction determines
220how good a programmer you are, and that’s the subject of the rest of the book.
2219
222Chapter 2
223Metaphors for a Richer
224Understanding of Software
225Development
226cc2e.com/0278 Contents
227â– 2.1 The Importance of Metaphors: page 9
228â– 2.2 How to Use Software Metaphors: page 11
229â– 2.3 Common Software Metaphors: page 13
230Related Topic
231■Heuristics in design: “Design Is a Heuristic Process†in Section 5.1
232Computer science has some of the most colorful language of any field. In what other
233field can you walk into a sterile room, carefully controlled at 68°F, and find viruses,
234Trojan horses, worms, bugs, bombs, crashes, flames, twisted sex changers, and fatal
235errors?
236These graphic metaphors describe specific software phenomena. Equally vivid metaphors
237describe broader phenomena, and you can use them to improve your understanding
238of the software-development process.
239The rest of the book doesn’t directly depend on the discussion of metaphors in this
240chapter. Skip it if you want to get to the practical suggestions. Read it if you want to
241think about software development more clearly.
2422.1 The Importance of Metaphors
243Important developments often arise out of analogies. By comparing a topic you understand
244poorly to something similar you understand better, you can come up with
245insights that result in a better understanding of the less-familiar topic. This use of metaphor
246is called “modeling.â€
247The history of science is full of discoveries based on exploiting the power of metaphors.
248The chemist Kekulé had a dream in which he saw a snake grasp its tail in its
249mouth. When he awoke, he realized that a molecular structure based on a similar ring
250shape would account for the properties of benzene. Further experimentation confirmed
251the hypothesis (Barbour 1966).
25210 Chapter 2: Metaphors for a Richer Understanding of Software Development
253The kinetic theory of gases was based on a “billiard-ball†model. Gas molecules were
254thought to have mass and to collide elastically, as billiard balls do, and many useful
255theorems were developed from this model.
256The wave theory of light was developed largely by exploring similarities between light
257and sound. Light and sound have amplitude (brightness, loudness), frequency (color,
258pitch), and other properties in common. The comparison between the wave theories
259of sound and light was so productive that scientists spent a great deal of effort looking
260for a medium that would propagate light the way air propagates sound. They even
261gave it a name —“etherâ€â€”but they never found the medium. The analogy that had been
262so fruitful in some ways proved to be misleading in this case.
263In general, the power of models is that they’re vivid and can be grasped as conceptual
264wholes. They suggest properties, relationships, and additional areas of inquiry. Sometimes
265a model suggests areas of inquiry that are misleading, in which case the metaphor
266has been overextended. When the scientists looked for ether, they overextended
267their model.
268As you might expect, some metaphors are better than others. A good metaphor is simple,
269relates well to other relevant metaphors, and explains much of the experimental
270evidence and other observed phenomena.
271Consider the example of a heavy stone swinging back and forth on a string. Before
272Galileo, an Aristotelian looking at the swinging stone thought that a heavy object
273moved naturally from a higher position to a state of rest at a lower one. The Aristotelian
274would think that what the stone was really doing was falling with difficulty. When
275Galileo saw the swinging stone, he saw a pendulum. He thought that what the stone
276was really doing was repeating the same motion again and again, almost perfectly.
277The suggestive powers of the two models are quite different. The Aristotelian who saw
278the swinging stone as an object falling would observe the stone’s weight, the height to
279which it had been raised, and the time it took to come to rest. For Galileo’s pendulum
280model, the prominent factors were different. Galileo observed the stone’s weight, the
281radius of the pendulum’s swing, the angular displacement, and the time per swing.
282Galileo discovered laws the Aristotelians could not discover because their model led
283them to look at different phenomena and ask different questions.
284Metaphors contribute to a greater understanding of software-development issues in
285the same way that they contribute to a greater understanding of scientific questions.
286In his 1973 Turing Award lecture, Charles Bachman described the change from the
287prevailing earth-centered view of the universe to a sun-centered view. Ptolemy’s earthcentered
288model had lasted without serious challenge for 1400 years. Then in 1543,
289Copernicus introduced a heliocentric theory, the idea that the sun rather than the
290earth was the center of the universe. This change in mental models led ultimately to
291the discovery of new planets, the reclassification of the moon as a satellite rather than
292as a planet, and a different understanding of humankind’s place in the universe.
2932.2 How to Use Software Metaphors 11
294The value of metaphors
295should not be underestimated.
296Metaphors have the
297virtue of an expected behavior
298that is understood by all.
299Unnecessary communication
300and misunderstandings are
301reduced. Learning and education
302are quicker. In effect,
303metaphors are a way of
304internalizing and abstracting
305concepts, allowing one’s
306thinking to be on a higher
307plane and low-level mistakes
308to be avoided.
309—Fernando J. Corbató
310Bachman compared the Ptolemaic-to-Copernican change in astronomy to the change
311in computer programming in the early 1970s. When Bachman made the comparison
312in 1973, data processing was changing from a computer-centered view of information
313systems to a database-centered view. Bachman pointed out that the ancients of data
314processing wanted to view all data as a sequential stream of cards flowing through a
315computer (the computer-centered view). The change was to focus on a pool of data on
316which the computer happened to act (a database-oriented view).
317Today it’s difficult to imagine anyone thinking that the sun moves around the earth.
318Similarly, it’s difficult to imagine a programmer thinking that all data could be viewed
319as a sequential stream of cards. In both cases, once the old theory has been discarded,
320it seems incredible that anyone ever believed it at all. More fantastically, people who
321believed the old theory thought the new theory was just as ridiculous then as you
322think the old theory is now.
323The earth-centered view of the universe hobbled astronomers who clung to it after a
324better theory was available. Similarly, the computer-centered view of the computing
325universe hobbled computer scientists who held on to it after the database-centered
326theory was available.
327It’s tempting to trivialize the power of metaphors. To each of the earlier examples, the
328natural response is to say, “Well, of course the right metaphor is more useful. The
329other metaphor was wrong!†Though that’s a natural reaction, it’s simplistic. The history
330of science isn’t a series of switches from the “wrong†metaphor to the “right†one.
331It’s a series of changes from “worse†metaphors to “better†ones, from less inclusive to
332more inclusive, from suggestive in one area to suggestive in another.
333In fact, many models that have been replaced by better models are still useful. Engineers
334still solve most engineering problems by using Newtonian dynamics even though, theoretically,
335Newtonian dynamics have been supplanted by Einsteinian theory.
336Software development is a younger field than most other sciences. It’s not yet mature
337enough to have a set of standard metaphors. Consequently, it has a profusion of complementary
338and conflicting metaphors. Some are better than others. Some are worse.
339How well you understand the metaphors determines how well you understand software
340development.
3412.2 How to Use Software Metaphors
342A software metaphor is more like a searchlight than a road map. It doesn’t tell you
343where to find the answer; it tells you how to look for it. A metaphor serves more as a
344heuristic than it does as an algorithm.
345An algorithm is a set of well-defined instructions for carrying out a particular task. An
346algorithm is predictable, deterministic, and not subject to chance. An algorithm tells
347KEY POINT
34812 Chapter 2: Metaphors for a Richer Understanding of Software Development
349you how to go from point A to point B with no detours, no side trips to points D, E,
350and F, and no stopping to smell the roses or have a cup of joe.
351A heuristic is a technique that helps you look for an answer. Its results are subject to
352chance because a heuristic tells you only how to look, not what to find. It doesn’t tell
353you how to get directly from point A to point B; it might not even know where point A
354and point B are. In effect, a heuristic is an algorithm in a clown suit. It’s less predictable,
355it’s more fun, and it comes without a 30-day, money-back guarantee.
356Here is an algorithm for driving to someone’s house: Take Highway 167 south to Puyallup.
357Take the South Hill Mall exit and drive 4.5 miles up the hill. Turn right at the
358light by the grocery store, and then take the first left. Turn into the driveway of the
359large tan house on the left, at 714 North Cedar.
360Cross-Reference For details
361on how to use heuristics in
362designing software, see
363“Design Is a Heuristic Processâ€
364in Section 5.1.
365Here’s a heuristic for getting to someone’s house: Find the last letter we mailed you.
366Drive to the town in the return address. When you get to town, ask someone where
367our house is. Everyone knows us—someone will be glad to help you. If you can’t find
368anyone, call us from a public phone, and we’ll come get you.
369The difference between an algorithm and a heuristic is subtle, and the two terms overlap
370somewhat. For the purposes of this book, the main difference between the two is
371the level of indirection from the solution. An algorithm gives you the instructions
372directly. A heuristic tells you how to discover the instructions for yourself, or at least
373where to look for them.
374Having directions that told you exactly how to solve your programming problems
375would certainly make programming easier and the results more predictable. But programming
376science isn’t yet that advanced and may never be. The most challenging
377part of programming is conceptualizing the problem, and many errors in programming
378are conceptual errors. Because each program is conceptually unique, it’s difficult
379or impossible to create a general set of directions that lead to a solution in every case.
380Thus, knowing how to approach problems in general is at least as valuable as knowing
381specific solutions for specific problems.
382How do you use software metaphors? Use them to give you insight into your programming
383problems and processes. Use them to help you think about your programming
384activities and to help you imagine better ways of doing things. You won’t be able to
385look at a line of code and say that it violates one of the metaphors described in this
386chapter. Over time, though, the person who uses metaphors to illuminate the software-
387development process will be perceived as someone who has a better understanding
388of programming and produces better code faster than people who don’t use them.
3892.3 Common Software Metaphors 13
3902.3 Common Software Metaphors
391A confusing abundance of metaphors has grown up around software development.
392David Gries says writing software is a science (1981). Donald Knuth says it’s an art
393(1998). Watts Humphrey says it’s a process (1989). P. J. Plauger and Kent Beck say it’s
394like driving a car, although they draw nearly opposite conclusions (Plauger 1993,
395Beck 2000). Alistair Cockburn says it’s a game (2002). Eric Raymond says it’s like a
396bazaar (2000). Andy Hunt and Dave Thomas say it’s like gardening. Paul Heckel says
397it’s like filming Snow White and the Seven Dwarfs (1994). Fred Brooks says that it’s like
398farming, hunting werewolves, or drowning with dinosaurs in a tar pit (1995). Which
399are the best metaphors?
400Software Penmanship: Writing Code
401The most primitive metaphor for software development grows out of the expression
402“writing code.†The writing metaphor suggests that developing a program is like writing
403a casual letter—you sit down with pen, ink, and paper and write it from start to finish. It
404doesn’t require any formal planning, and you figure out what you want to say as you go.
405Many ideas derive from the writing metaphor. Jon Bentley says you should be able to
406sit down by the fire with a glass of brandy, a good cigar, and your favorite hunting dog
407to enjoy a “literate program†the way you would a good novel. Brian Kernighan and
408P. J. Plauger named their programming-style book The Elements of Programming Style
409(1978) after the writing-style book The Elements of Style (Strunk and White 2000).
410Programmers often talk about “program readability.â€
411For an individual’s work or for small-scale projects, the letter-writing metaphor works
412adequately, but for other purposes it leaves the party early—it doesn’t describe software
413development fully or adequately. Writing is usually a one-person activity,
414whereas a software project will most likely involve many people with many different
415responsibilities. When you finish writing a letter, you stuff it into an envelope and mail
416it. You can’t change it anymore, and for all intents and purposes it’s complete. Software
417isn’t as difficult to change and is hardly ever fully complete. As much as 90 percent
418of the development effort on a typical software system comes after its initial
419release, with two-thirds being typical (Pigoski 1997). In writing, a high premium is
420placed on originality. In software construction, trying to create truly original work is
421often less effective than focusing on the reuse of design ideas, code, and test cases
422from previous projects. In short, the writing metaphor implies a software-development
423process that’s too simple and rigid to be healthy.
4241
4252
4263
427HARD DATA
42814 Chapter 2: Metaphors for a Richer Understanding of Software Development
429Plan to throw one away; you
430will, anyhow.
431—Fred Brooks
432If you plan to throw one
433away, you will throw away
434two.
435—Craig Zerouni
436Unfortunately, the letter-writing metaphor has been perpetuated by one of the most
437popular software books on the planet, Fred Brooks’s The Mythical Man-Month (Brooks
4381995). Brooks says, “Plan to throw one away; you will, anyhow.†This conjures up an
439image of a pile of half-written drafts thrown into a wastebasket, as shown in Figure 2-1.
440Figure 2-1 The letter-writing metaphor suggests that the software process relies on expensive
441trial and error rather than careful planning and design.
442Planning to throw one away might be practical when you’re writing a polite how-doyou-
443do to your aunt. But extending the metaphor of “writing†software to a plan to
444throw one away is poor advice for software development, where a major system
445already costs as much as a 10-story office building or an ocean liner. It’s easy to grab
446the brass ring if you can afford to sit on your favorite wooden pony for an unlimited
447number of spins around the carousel. The trick is to get it the first time around—or to
448take several chances when they’re cheapest. Other metaphors better illuminate ways
449of attaining such goals.
450Software Farming: Growing a System
451In contrast to the rigid writing metaphor, some software developers say you should
452envision creating software as something like planting seeds and growing crops. You
453design a piece, code a piece, test a piece, and add it to the system a little bit at a time.
454By taking small steps, you minimize the trouble you can get into at any one time.
455Sometimes a good technique is described with a bad metaphor. In such cases, try to
456keep the technique and come up with a better metaphor. In this case, the incremental
457technique is valuable, but the farming metaphor is terrible.
458Further Reading For an
459illustration of a different
460farming metaphor, one that’s
461applied to software maintenance,
462see the chapter “On
463the Origins of Designer Intuitionâ€
464in Rethinking Systems
465Analysis and Design (Weinberg
4661988).
467The idea of doing a little bit at a time might bear some resemblance to the way crops
468grow, but the farming analogy is weak and uninformative, and it’s easy to replace with
469the better metaphors described in the following sections. It’s hard to extend the farming
470metaphor beyond the simple idea of doing things a little bit at a time. If you buy
471into the farming metaphor, imagined in Figure 2-2, you might find yourself talking
472about fertilizing the system plan, thinning the detailed design, increasing code yields
473through effective land management, and harvesting the code itself. You’ll talk about
474KEY POINT
4752.3 Common Software Metaphors 15
476rotating in a crop of C++ instead of barley, of letting the land rest for a year to increase
477the supply of nitrogen in the hard disk.
478The weakness in the software-farming metaphor is its suggestion that you don’t have
479any direct control over how the software develops. You plant the code seeds in the
480spring. Farmer’s Almanac and the Great Pumpkin willing, you’ll have a bumper crop of
481code in the fall.
482Figure 2-2 It’s hard to extend the farming metaphor to software development
483appropriately.
484Software Oyster Farming: System Accretion
485Sometimes people talk about growing software when they really mean software accretion.
486The two metaphors are closely related, but software accretion is the more insightful
487image. “Accretion,†in case you don’t have a dictionary handy, means any growth or
488increase in size by a gradual external addition or inclusion. Accretion describes the
489way an oyster makes a pearl, by gradually adding small amounts of calcium carbonate.
490In geology, “accretion†means a slow addition to land by the deposit of waterborne
491sediment. In legal terms, “accretion†means an increase of land along the shores of a
492body of water by the deposit of waterborne sediment.
493Cross-Reference For details
494on how to apply incremental
495strategies to system integration,
496see Section 29.2, “Integration
497Frequency—Phased
498or Incremental?â€
499This doesn’t mean that you have to learn how to make code out of waterborne sediment;
500it means that you have to learn how to add to your software systems a small
501amount at a time. Other words closely related to accretion are “incremental,†“iterative,â€
502“adaptive,†and “evolutionary.†Incremental designing, building, and testing are
503some of the most powerful software-development concepts available.
504In incremental development, you first make the simplest possible version of the system
505that will run. It doesn’t have to accept realistic input, it doesn’t have to perform
506realistic manipulations on data, it doesn’t have to produce realistic output—it just has
507to be a skeleton strong enough to hold the real system as it’s developed. It might call
508dummy classes for each of the basic functions you have identified. This basic beginning
509is like the oyster’s beginning a pearl with a small grain of sand.
510After you’ve formed the skeleton, little by little you lay on the muscle and skin. You
511change each of the dummy classes to real classes. Instead of having your program
51216 Chapter 2: Metaphors for a Richer Understanding of Software Development
513pretend to accept input, you drop in code that accepts real input. Instead of having
514your program pretend to produce output, you drop in code that produces real output.
515You add a little bit of code at a time until you have a fully working system.
516The anecdotal evidence in favor of this approach is impressive. Fred Brooks, who in
5171975 advised building one to throw away, said that nothing in the decade after he
518wrote his landmark book The Mythical Man-Month so radically changed his own
519practice or its effectiveness as incremental development (1995). Tom Gilb made the
520same point in his breakthrough book, Principles of Software Engineering Management
521(1988), which introduced Evolutionary Delivery and laid the groundwork for much
522of today’s Agile programming approach. Numerous current methodologies are based
523on this idea (Beck 2000, Cockburn 2002, Highsmith 2002, Reifer 2002, Martin
5242003, Larman 2004).
525As a metaphor, the strength of the incremental metaphor is that it doesn’t overpromise.
526It’s harder than the farming metaphor to extend inappropriately. The image of an oyster
527forming a pearl is a good way to visualize incremental development, or accretion.
528Software Construction: Building Software
529The image of “building†software is more useful than that of “writing†or “growingâ€
530software. It’s compatible with the idea of software accretion and provides more
531detailed guidance. Building software implies various stages of planning, preparation,
532and execution that vary in kind and degree depending on what’s being built. When
533you explore the metaphor, you find many other parallels.
534Building a four-foot tower requires a steady hand, a level surface, and 10 undamaged
535beer cans. Building a tower 100 times that size doesn’t merely require 100 times as
536many beer cans. It requires a different kind of planning and construction altogether.
537If you’re building a simple structure—a doghouse, say—you can drive to the lumber
538store and buy some wood and nails. By the end of the afternoon, you’ll have a new
539house for Fido. If you forget to provide for a door, as shown in Figure 2-3, or make
540some other mistake, it’s not a big problem; you can fix it or even start over from the
541beginning. All you’ve wasted is part of an afternoon. This loose approach is appropriate
542for small software projects too. If you use the wrong design for 1000 lines of code,
543you can refactor or start over completely without losing much.
544KEY POINT
5452.3 Common Software Metaphors 17
546Figure 2-3 The penalty for a mistake on a simple structure is only a little time and maybe
547some embarrassment.
548If you’re building a house, the building process is more complicated, and so are the
549consequences of poor design. First you have to decide what kind of house you want to
550build—analogous in software development to problem definition. Then you and an
551architect have to come up with a general design and get it approved. This is similar to
552software architectural design. You draw detailed blueprints and hire a contractor. This
553is similar to detailed software design. You prepare the building site, lay a foundation,
554frame the house, put siding and a roof on it, and plumb and wire it. This is similar to
555software construction. When most of the house is done, the landscapers, painters,
556and decorators come in to make the best of your property and the home you’ve built.
557This is similar to software optimization. Throughout the process, various inspectors
558come to check the site, foundation, frame, wiring, and other inspectables. This is similar
559to software reviews and inspections.
560Greater complexity and size imply greater consequences in both activities. In building
561a house, materials are somewhat expensive, but the main expense is labor. Ripping
562out a wall and moving it six inches is expensive not because you waste a lot of nails
563but because you have to pay the people for the extra time it takes to move the wall. You
564have to make the design as good as possible, as suggested by Figure 2-4, so that you
565don’t waste time fixing mistakes that could have been avoided. In building a software
566product, materials are even less expensive, but labor costs just as much. Changing a
567report format is just as expensive as moving a wall in a house because the main cost
568component in both cases is people’s time.
56918 Chapter 2: Metaphors for a Richer Understanding of Software Development
570Figure 2-4 More complicated structures require more careful planning.
571What other parallels do the two activities share? In building a house, you won’t try to
572build things you can buy already built. You’ll buy a washer and dryer, dishwasher,
573refrigerator, and freezer. Unless you’re a mechanical wizard, you won’t consider building
574them yourself. You’ll also buy prefabricated cabinets, counters, windows, doors,
575and bathroom fixtures. If you’re building a software system, you’ll do the same thing.
576You’ll make extensive use of high-level language features rather than writing your own
577operating-system-level code. You might also use prebuilt libraries of container classes,
578scientific functions, user interface classes, and database-manipulation classes. It generally
579doesn’t make sense to code things you can buy ready-made.
580If you’re building a fancy house with first-class furnishings, however, you might have
581your cabinets custom-made. You might have a dishwasher, refrigerator, and freezer
582built in to look like the rest of your cabinets. You might have windows custom-made in
583unusual shapes and sizes. This customization has parallels in software development.
584If you’re building a first-class software product, you might build your own scientific
585functions for better speed or accuracy. You might build your own container classes,
586user interface classes, and database classes to give your system a seamless, perfectly
587consistent look and feel.
588Both building construction and software construction benefit from appropriate levels
589of planning. If you build software in the wrong order, it’s hard to code, hard to test,
590and hard to debug. It can take longer to complete, or the project can fall apart because
591everyone’s work is too complex and therefore too confusing when it’s all combined.
592Careful planning doesn’t necessarily mean exhaustive planning or over-planning. You
593can plan out the structural supports and decide later whether to put in hardwood
594floors or carpeting, what color to paint the walls, what roofing material to use, and so
5952.3 Common Software Metaphors 19
596on. A well-planned project improves your ability to change your mind later about
597details. The more experience you have with the kind of software you’re building, the
598more details you can take for granted. You just want to be sure that you plan enough
599so that lack of planning doesn’t create major problems later.
600The construction analogy also helps explain why different software projects benefit
601from different development approaches. In building, you’d use different levels of planning,
602design, and quality assurance if you’re building a warehouse or a toolshed than if
603you’re building a medical center or a nuclear reactor. You’d use still different approaches
604for building a school, a skyscraper, or a three-bedroom home. Likewise, in software you
605might generally use flexible, lightweight development approaches, but sometimes you’ll
606need rigid, heavyweight approaches to achieve safety goals and other goals.
607Making changes in the software brings up another parallel with building construction.
608To move a wall six inches costs more if the wall is load-bearing than if it’s merely
609a partition between rooms. Similarly, making structural changes in a program costs
610more than adding or deleting peripheral features.
611Finally, the construction analogy provides insight into extremely large software projects.
612Because the penalty for failure in an extremely large structure is severe, the structure has
613to be over-engineered. Builders make and inspect their plans carefully. They build in
614margins of safety; it’s better to pay 10 percent more for stronger material than to have a
615skyscraper fall over. A great deal of attention is paid to timing. When the Empire State
616Building was built, each delivery truck had a 15-minute margin in which to make its
617delivery. If a truck wasn’t in place at the right time, the whole project was delayed.
618Likewise, for extremely large software projects, planning of a higher order is needed
619than for projects that are merely large. Capers Jones reports that a software system
620with one million lines of code requires an average of 69 kinds of documentation
621(1998). The requirements specification for such a system would typically be about
6224000–5000 pages long, and the design documentation can easily be two or three
623times as extensive as the requirements. It’s unlikely that an individual would be able
624to understand the complete design for a project of this size—or even read it. A greater
625degree of preparation is appropriate.
626We build software projects comparable in economic size to the Empire State Building,
627and technical and managerial controls of similar stature are needed.
628Further Reading For some
629good comments about
630extending the construction
631metaphor, see “What Supports
632the Roof?†(Starr 2003).
633The building-construction metaphor could be extended in a variety of other directions,
634which is why the metaphor is so powerful. Many terms common in software development
635derive from the building metaphor: software architecture, scaffolding, construction,
636foundation classes, and tearing code apart. You’ll probably hear many more.
63720 Chapter 2: Metaphors for a Richer Understanding of Software Development
638Applying Software Techniques: The Intellectual Toolbox
639People who are effective at developing high-quality software have spent years accumulating
640dozens of techniques, tricks, and magic incantations. The techniques are not
641rules; they are analytical tools. A good craftsman knows the right tool for the job and
642knows how to use it correctly. Programmers do, too. The more you learn about programming,
643the more you fill your mental toolbox with analytical tools and the knowledge
644of when to use them and how to use them correctly.
645Cross-Reference For details
646on selecting and combining
647methods in design, see Section
6485.3, “Design Building
649Blocks: Heuristics.â€
650In software, consultants sometimes tell you to buy into certain software-development
651methods to the exclusion of other methods. That’s unfortunate because if you buy
652into any single methodology 100 percent, you’ll see the whole world in terms of that
653methodology. In some instances, you’ll miss opportunities to use other methods better
654suited to your current problem. The toolbox metaphor helps to keep all the methods,
655techniques, and tips in perspective—ready for use when appropriate.
656Combining Metaphors
657Because metaphors are heuristic rather than algorithmic, they are not mutually exclusive.
658You can use both the accretion and the construction metaphors. You can use
659writing if you want to, and you can combine writing with driving, hunting for werewolves,
660or drowning in a tar pit with dinosaurs. Use whatever metaphor or combination
661of metaphors stimulates your own thinking or communicates well with others on
662your team.
663Using metaphors is a fuzzy business. You have to extend them to benefit from the
664heuristic insights they provide. But if you extend them too far or in the wrong direction,
665they’ll mislead you. Just as you can misuse any powerful tool, you can misuse
666metaphors, but their power makes them a valuable part of your intellectual toolbox.
667Additional Resources
668cc2e.com/0285 Among general books on metaphors, models, and paradigms, the touchstone book is
669by Thomas Kuhn.
670Kuhn, Thomas S. The Structure of Scientific Revolutions, 3d ed. Chicago, IL: The University
671of Chicago Press, 1996. Kuhn’s book on how scientific theories emerge, evolve, and
672succumb to other theories in a Darwinian cycle set the philosophy of science on its ear
673when it was first published in 1962. It’s clear and short, and it’s loaded with interesting
674examples of the rise and fall of metaphors, models, and paradigms in science.
675Floyd, Robert W. “The Paradigms of Programming.†1978 Turing Award Lecture.
676Communications of the ACM, August 1979, pp. 455–60. This is a fascinating discussion
677of models in software development, and Floyd applies Kuhn’s ideas to the topic.
678KEY POINT
679KEY POINT
680Key Points 21
681Key Points
682â– Metaphors are heuristics, not algorithms. As such, they tend to be a little sloppy.
683â– Metaphors help you understand the software-development process by relating it
684to other activities you already know about.
685â– Some metaphors are better than others.
686â– Treating software construction as similar to building construction suggests that
687careful preparation is needed and illuminates the difference between large and
688small projects.
689â– Thinking of software-development practices as tools in an intellectual toolbox
690suggests further that every programmer has many tools and that no single tool
691is right for every job. Choosing the right tool for each problem is one key to
692being an effective programmer.
693â– Metaphors are not mutually exclusive. Use the combination of metaphors that
694works best for you.
695
69623
697Chapter 3
698Measure Twice, Cut Once:
699Upstream Prerequisites
700cc2e.com/0309 Contents
701â– 3.1 Importance of Prerequisites: page 24
702■3.2 Determine the Kind of Software You’re Working On: page 31
703â– 3.3 Problem-Definition Prerequisite: page 36
704â– 3.4 Requirements Prerequisite: page 38
705â– 3.5 Architecture Prerequisite: page 43
706â– 3.6 Amount of Time to Spend on Upstream Prerequisites: page 55
707Related Topics
708â– Key construction decisions: Chapter 4
709â– Effect of project size on construction and prerequisites: Chapter 27
710â– Relationship between quality goals and construction activities: Chapter 20
711â– Managing construction: Chapter 28
712â– Design: Chapter 5
713Before beginning construction of a house, a builder reviews blueprints, checks that all
714permits have been obtained, and surveys the house’s foundation. A builder prepares
715for building a skyscraper one way, a housing development a different way, and a doghouse
716a third way. No matter what the project, the preparation is tailored to the
717project’s specific needs and done conscientiously before construction begins.
718This chapter describes the work that must be done to prepare for software construction.
719As with building construction, much of the success or failure of the project has
720already been determined before construction begins. If the foundation hasn’t been
721laid well or the planning is inadequate, the best you can do during construction is to
722keep damage to a minimum.
723The carpenter’s saying, “Measure twice, cut once†is highly relevant to the construction
724part of software development, which can account for as much as 65 percent of the
725total project costs. The worst software projects end up doing construction two or
72624 Chapter 3: Measure Twice, Cut Once: Upstream Prerequisites
727three times or more. Doing the most expensive part of the project twice is as bad an
728idea in software as it is in any other line of work.
729Although this chapter lays the groundwork for successful software construction, it
730doesn’t discuss construction directly. If you’re feeling carnivorous or you’re already
731well versed in the software-engineering life cycle, look for the construction meat
732beginning in Chapter 5, “Design in Construction.†If you don’t like the idea of prerequisites
733to construction, review Section 3.2, “Determine the Kind of Software
734You’re Working On,†to see how prerequisites apply to your situation, and then take
735a look at the data in Section 3.1, which describes the cost of not doing prerequisites.
7363.1 Importance of Prerequisites
737Cross-Reference Paying
738attention to quality is also
739the best way to improve productivity.
740For details, see
741Section 20.5, “The General
742Principle of Software
743Quality.â€
744A common denominator of programmers who build high-quality software is their use
745of high-quality practices. Such practices emphasize quality at the beginning, middle,
746and end of a project.
747If you emphasize quality at the end of a project, you emphasize system testing. Testing
748is what many people think of when they think of software quality assurance. Testing,
749however, is only one part of a complete quality-assurance strategy, and it’s not the
750most influential part. Testing can’t detect a flaw such as building the wrong product or
751building the right product in the wrong way. Such flaws must be worked out earlier
752than in testing—before construction begins.
753If you emphasize quality in the middle of the project, you emphasize construction
754practices. Such practices are the focus of most of this book.
755If you emphasize quality at the beginning of the project, you plan for, require, and
756design a high-quality product. If you start the process with designs for a Pontiac Aztek,
757you can test it all you want to, and it will never turn into a Rolls-Royce. You might
758build the best possible Aztek, but if you want a Rolls-Royce, you have to plan from the
759beginning to build one. In software development, you do such planning when you
760define the problem, when you specify the solution, and when you design the solution.
761Since construction is in the middle of a software project, by the time you get to construction,
762the earlier parts of the project have already laid some of the groundwork for
763success or failure. During construction, however, you should at least be able to determine
764how good your situation is and to back up if you see the black clouds of failure
765looming on the horizon. The rest of this chapter describes in detail why proper preparation
766is important and tells you how to determine whether you’re really ready to
767begin construction.
768KEY POINT
7693.1 Importance of Prerequisites 25
770Do Prerequisites Apply to Modern Software Projects?
771The methodology used
772should be based on choice of
773the latest and best, and not
774based on ignorance. It
775should also be laced liberally
776with the old and dependable.
777—Harlan Mills
778Some people have asserted that upstream activities such as architecture, design, and
779project planning aren’t useful on modern software projects. In the main, such assertions
780are not well supported by research, past or present, or by current data. (See the
781rest of this chapter for details.) Opponents of prerequisites typically show examples of
782prerequisites that have been done poorly and then point out that such work isn’t
783effective. Upstream activities can be done well, however, and industry data from the
7841970s to the present day indicates that projects will run best if appropriate preparation
785activities are done before construction begins in earnest.
786The overarching goal of preparation is risk reduction: a good project planner clears
787major risks out of the way as early as possible so that the bulk of the project can proceed
788as smoothly as possible. By far the most common project risks in software development
789are poor requirements and poor project planning, thus preparation tends to
790focus on improving requirements and project plans.
791Preparation for construction is not an exact science, and the specific approach to risk
792reduction must be decided project by project. Details can vary greatly among projects.
793For more on this, see Section 3.2.
794Causes of Incomplete Preparation
795You might think that all professional programmers know about the importance of
796preparation and check that the prerequisites have been satisfied before jumping into
797construction. Unfortunately, that isn’t so.
798Further Reading For a
799description of a professional
800development program that
801cultivates these skills, see
802Chapter 16 of Professional
803Software Development
804(McConnell 2004).
805cc2e.com/0316
806A common cause of incomplete preparation is that the developers who are assigned to
807work on the upstream activities do not have the expertise to carry out their assignments.
808The skills needed to plan a project, create a compelling business case, develop comprehensive
809and accurate requirements, and create high-quality architectures are far from
810trivial, but most developers have not received training in how to perform these activities.
811When developers don’t know how to do upstream work, the recommendation to “do
812more upstream work†sounds like nonsense: If the work isn’t being done well in the first
813place, doing more of it will not be useful! Explaining how to perform these activities is
814beyond the scope of this book, but the “Additional Resources†sections at the end of this
815chapter provide numerous options for gaining that expertise.
816Some programmers do know how to perform upstream activities, but they don’t prepare
817because they can’t resist the urge to begin coding as soon as possible. If you feed your
818KEY POINT
81926 Chapter 3: Measure Twice, Cut Once: Upstream Prerequisites
820horse at this trough, I have two suggestions. Suggestion 1: Read the argument in the next
821section. It may tell you a few things you haven’t thought of. Suggestion 2: Pay attention to
822the problems you experience. It takes only a few large programs to learn that you can
823avoid a lot of stress by planning ahead. Let your own experience be your guide.
824A final reason that programmers don’t prepare is that managers are notoriously
825unsympathetic to programmers who spend time on construction prerequisites. People
826like Barry Boehm, Grady Booch, and Karl Wiegers have been banging the requirements
827and design drums for 25 years, and you’d expect that managers would have
828started to understand that software development is more than coding.
829Further Reading For many
830entertaining variations on
831this theme, read Gerald
832Weinberg’s classic, The Psychology
833of Computer Programming
834(Weinberg 1998).
835A few years ago, however, I was working on a Department of Defense project that was
836focusing on requirements development when the Army general in charge of the
837project came for a visit. We told him that we were developing requirements and that
838we were mainly talking to our customer, capturing requirements, and outlining the
839design. He insisted on seeing code anyway. We told him there was no code, but he
840walked around a work bay of 100 people, determined to catch someone programming.
841Frustrated by seeing so many people away from their desks or working on
842requirements and design, the large, round man with the loud voice finally pointed to
843the engineer sitting next to me and bellowed, “What’s he doing? He must be writing
844code!†In fact, the engineer was working on a document-formatting utility, but the general
845wanted to find code, thought it looked like code, and wanted the engineer to be
846working on code, so we told him it was code.
847This phenomenon is known as the WISCA or WIMP syndrome: Why Isn’t Sam Coding
848Anything? or Why Isn’t Mary Programming?
849If the manager of your project pretends to be a brigadier general and orders you to
850start coding right away, it’s easy to say, “Yes, Sir!†(What’s the harm? The old guy must
851know what he’s talking about.) This is a bad response, and you have several better
852alternatives. First, you can flatly refuse to do work in an ineffective order. If your relationships
853with your boss and your bank account are healthy enough for you to be able
854to do this, good luck.
855A second questionable alternative is pretending to be coding when you’re not. Put an
856old program listing on the corner of your desk. Then go right ahead and develop your
857requirements and architecture, with or without your boss’s approval. You’ll do the
858project faster and with higher-quality results. Some people find this approach ethically
859objectionable, but from your boss’s perspective, ignorance will be bliss.
860Third, you can educate your boss in the nuances of technical projects. This is a good
861approach because it increases the number of enlightened bosses in the world. The
862next subsection presents an extended rationale for taking the time to do prerequisites
863before construction.
8643.1 Importance of Prerequisites 27
865Finally, you can find another job. Despite economic ups and downs, good programmers
866are perennially in short supply (BLS 2002), and life is too short to work in an
867unenlightened programming shop when plenty of better alternatives are available.
868Utterly Compelling and Foolproof Argument for Doing Prerequisites
869Before Construction
870Suppose you’ve already been to the mountain of problem definition, walked a mile
871with the man of requirements, shed your soiled garments at the fountain of architecture,
872and bathed in the pure waters of preparedness. Then you know that before you
873implement a system, you need to understand what the system is supposed to do and
874how it’s supposed to do it.
875Part of your job as a technical employee is to educate the nontechnical people around
876you about the development process. This section will help you deal with managers
877and bosses who have not yet seen the light. It’s an extended argument for doing
878requirements and architecture—getting the critical aspects right—before you begin coding,
879testing, and debugging. Learn the argument, and then sit down with your boss
880and have a heart-to-heart talk about the programming process.
881Appeal to Logic
882One of the key ideas in effective programming is that preparation is important. It
883makes sense that before you start working on a big project, you should plan the
884project. Big projects require more planning; small projects require less. From a management
885point of view, planning means determining the amount of time, number of
886people, and number of computers the project will need. From a technical point of
887view, planning means understanding what you want to build so that you don’t waste
888money building the wrong thing. Sometimes users aren’t entirely sure what they want
889at first, so it might take more effort than seems ideal to find out what they really want.
890But that’s cheaper than building the wrong thing, throwing it away, and starting over.
891It’s also important to think about how to build the system before you begin to build it.
892You don’t want to spend a lot of time and money going down blind alleys when
893there’s no need to, especially when that increases costs.
894Appeal to Analogy
895Building a software system is like any other project that takes people and money. If
896you’re building a house, you make architectural drawings and blueprints before you
897begin pounding nails. You’ll have the blueprints reviewed and approved before you
898pour any concrete. Having a technical plan counts just as much in software.
899KEY POINT
90028 Chapter 3: Measure Twice, Cut Once: Upstream Prerequisites
901You don’t start decorating the Christmas tree until you’ve put it in the stand. You don’t
902start a fire until you’ve opened the flue. You don’t go on a long trip with an empty tank
903of gas. You don’t get dressed before you take a shower, and you don’t put your shoes
904on before your socks. You have to do things in the right order in software, too.
905Programmers are at the end of the software food chain. The architect consumes the
906requirements; the designer consumes the architecture; and the coder consumes
907the design.
908Compare the software food chain to a real food chain. In an ecologically sound environment,
909seagulls eat fresh salmon. That’s nourishing to them because the salmon ate
910fresh herring, and they in turn ate fresh water bugs. The result is a healthy food chain.
911In programming, if you have healthy food at each stage in the food chain, the result is
912healthy code written by happy programmers.
913In a polluted environment, the water bugs have been swimming in nuclear waste, the
914herring are contaminated by PCBs, and the salmon that eat the herring swam through
915oil spills. The seagulls are, unfortunately, at the end of the food chain, so they don’t eat
916just the oil in the bad salmon. They also eat the PCBs and the nuclear waste from the
917herring and the water bugs. In programming, if your requirements are contaminated,
918they contaminate the architecture, and the architecture in turn contaminates construction.
919This leads to grumpy, malnourished programmers and radioactive, polluted
920software that’s riddled with defects.
921If you are planning a highly iterative project, you will need to identify the critical
922requirements and architectural elements that apply to each piece you’re constructing
923before you begin construction. A builder who is building a housing development
924doesn’t need to know every detail of every house in the development before beginning
925construction on the first house. But the builder will survey the site, map out
926sewer and electrical lines, and so on. If the builder doesn’t prepare well, construction
927may be delayed when a sewer line needs to be dug under a house that’s already been
928constructed.
929Appeal to Data
930Studies over the last 25 years have proven conclusively that it pays to do things right
931the first time. Unnecessary changes are expensive.
9323.1 Importance of Prerequisites 29
933Researchers at Hewlett-Packard, IBM, Hughes Aircraft, TRW, and other organizations
934have found that purging an error by the beginning of construction allows rework to be
935done 10 to 100 times less expensively than when it’s done in the last part of the process,
936during system test or after release (Fagan 1976; Humphrey, Snyder, and Willis
9371991; Leffingwell 1997; Willis et al. 1998; Grady 1999; Shull et al. 2002; Boehm and
938Turner 2004).
939In general, the principle is to find an error as close as possible to the time at which it
940was introduced. The longer the defect stays in the software food chain, the more damage
941it causes further down the chain. Since requirements are done first, requirements
942defects have the potential to be in the system longer and to be more expensive. Defects
943inserted into the software upstream also tend to have broader effects than those
944inserted further downstream. That also makes early defects more expensive.
945Table 3-1 shows the relative expense of fixing defects depending on when they’re
946introduced and when they’re found.
947The data in Table 3-1 shows that, for example, an architecture defect that costs $1000
948to fix when the architecture is being created can cost $15,000 to fix during system
949test. Figure 3-1 illustrates the same phenomenon.
9501
9512
9523
953HARD DATA
9541
9552
9563
957HARD DATA
958Table 3-1 Average Cost of Fixing Defects Based on When They’re Introduced and Detected
959Time Detected
960Time Introduced Requirements Architecture Construction System Test Post-Release
961Requirements 1 3 5–10 10 10–100
962Architecture — 1 10 15 25–100
963Construction — — 1 10 10–25
964Source: Adapted from “Design and Code Inspections to Reduce Errors in Program Development†(Fagan 1976), Software Defect Removal
965(Dunn 1984), “Software Process Improvement at Hughes Aircraft†(Humphrey, Snyder, and Willis 1991), “Calculating the Return on
966Investment from More Effective Requirements Management†(Leffingwell 1997), “Hughes Aircraft’s Widespread Deployment of a
967Continuously Improving Software Process†(Willis et al. 1998), “An Economic Release Decision Model: Insights into Software Project
968Management†(Grady 1999), “What We Have Learned About Fighting Defects†(Shull et al. 2002), and Balancing Agility and Discipline:
969A Guide for the Perplexed (Boehm and Turner 2004).
97030 Chapter 3: Measure Twice, Cut Once: Upstream Prerequisites
971Figure 3-1 The cost to fix a defect rises dramatically as the time from when it’s introduced
972to when it’s detected increases. This remains true whether the project is highly sequential
973(doing 100 percent of requirements and design up front) or highly iterative (doing 5 percent
974of requirements and design up front).
975The average project still exerts most of its defect-correction effort on the right side of Figure
9763-1, which means that debugging and associated rework takes about 50 percent of
977the time spent in a typical software development cycle (Mills 1983; Boehm 1987a; Cooper
978and Mullen 1993; Fishman 1996; Haley 1996; Wheeler, Brykczynski, and Meeson
9791996; Jones 1998; Shull et al. 2002; Wiegers 2002). Dozens of companies have found
980that simply focusing on correcting defects earlier rather than later in a project can cut
981development costs and schedules by factors of two or more (McConnell 2004). This is
982a healthy incentive to find and fix your problems as early as you can.
983Boss-Readiness Test
984When you think your boss understands the importance of working on prerequisites
985before moving into construction, try the test below to be sure.
986Which of these statements are self-fulfilling prophecies?
987■We’d better start coding right away because we’re going to have a lot of debugging
988to do.
989■We haven’t planned much time for testing because we’re not going to find many
990defects.
991Phase in Which a
992Defect Is Introduced
993Requirements
994Architecture
995Construction
996System Test
997Requirements
998Architecture
999Construction Post-Release
1000Phase in Which a Defect Is Detected
1001Cost
10021
10032
10043
1005HARD DATA
10063.2 Determine the Kind of Software You’re Working On 31
1007■We’ve investigated requirements and design so much that I can’t think of any
1008major problems we’ll run into during coding or debugging.
1009All of these statements are self-fulfilling prophecies. Aim for the last one.
1010If you’re still not convinced that prerequisites apply to your project, the next section
1011will help you decide.
10123.2 Determine the Kind of Software You’re Working On
1013Capers Jones, Chief Scientist at Software Productivity Research, summarized 20 years
1014of software research by pointing out that he and his colleagues have seen 40 different
1015methods for gathering requirements, 50 variations in working on software designs,
1016and 30 kinds of testing applied to projects in more than 700 different programming
1017languages (Jones 2003).
1018Different kinds of software projects call for different balances between preparation
1019and construction. Every project is unique, but projects do tend to fall into general
1020development styles. Table 3-2 shows three of the most common kinds of projects and
1021lists the practices that are typically best suited to each kind of project.
1022Table 3-2 Typical Good Practices for Three Common Kinds of Software Projects
1023Kind of Software
1024Business Systems
1025Mission-Critical
1026Systems
1027Embedded
1028Life-Critical Systems
1029Typical
1030applications
1031Internet site
1032Intranet site
1033Inventory
1034management
1035Games
1036Management
1037information systems
1038Payroll system
1039Embedded software
1040Games
1041Internet site
1042Packaged software
1043Software tools
1044Web services
1045Avionics software
1046Embedded software
1047Medical devices
1048Operating systems
1049Packaged software
1050Life-cycle
1051models
1052Agile development
1053(Extreme Programming,
1054Scrum, timebox
1055development,
1056and so on)
1057Evolutionary
1058prototyping
1059Staged delivery
1060Evolutionary
1061delivery
1062Spiral development
1063Staged delivery
1064Spiral development
1065Evolutionary delivery
106632 Chapter 3: Measure Twice, Cut Once: Upstream Prerequisites
1067On real projects, you’ll find infinite variations on the three themes presented in this
1068table; however, the generalities in the table are illuminating. Business systems projects
1069tend to benefit from highly iterative approaches, in which planning, requirements,
1070Business Systems
1071Mission-Critical
1072Systems
1073Embedded
1074Life-Critical Systems
1075Planning and
1076management
1077Incremental project
1078planning
1079As-needed test and
1080QA planning
1081Informal change
1082control
1083Basic up-front
1084planning
1085Basic test planning
1086As-needed QA
1087planning
1088Formal change
1089control
1090Extensive up-front
1091planning
1092Extensive test
1093planning
1094Extensive QA
1095planning
1096Rigorous change
1097control
1098Requirements Informal requirements
1099specification
1100Semiformal requirements
1101specification
1102As-needed requirements
1103reviews
1104Formal requirements
1105specification
1106Formal requirements
1107inspections
1108Design Design and coding
1109are combined
1110Architectural design
1111Informal detailed
1112design
1113As-needed design
1114reviews
1115Architectural design
1116Formal architecture
1117inspections
1118Formal detailed
1119design
1120Formal detailed
1121design inspections
1122Construction Pair programming
1123or individual coding
1124Informal check-in
1125procedure or no
1126check-in procedure
1127Pair programming
1128or individual coding
1129Informal check-in
1130procedure
1131As-needed code
1132reviews
1133Pair programming or
1134individual coding
1135Formal check-in
1136procedure
1137Formal code
1138inspections
1139Testing
1140and QA
1141Developers test
1142their own code
1143Test-first
1144development
1145Little or no testing
1146by a separate test
1147group
1148Developers test
1149their own code
1150Test-first
1151development
1152Separate testing
1153group
1154Developers test their
1155own code
1156Test-first
1157development
1158Separate testing
1159group
1160Separate QA group
1161Deployment Informal deployment
1162procedure
1163Formal deployment
1164procedure
1165Formal deployment
1166procedure
1167Table 3-2 Typical Good Practices for Three Common Kinds of Software Projects
1168Kind of Software
11693.2 Determine the Kind of Software You’re Working On 33
1170and architecture are interleaved with construction, system testing, and quality-assurance
1171activities. Life-critical systems tend to require more sequential approaches—
1172requirements stability is part of what’s needed to ensure ultrahigh levels of reliability.
1173Iterative Approaches’ Effect on Prerequisites
1174Some writers have asserted that projects that use iterative techniques don’t need to
1175focus on prerequisites much at all, but that point of view is misinformed. Iterative
1176approaches tend to reduce the impact of inadequate upstream work, but they don’t
1177eliminate it. Consider the examples shown in Table 3-3 of projects that don’t focus on
1178prerequisites. One project is conducted sequentially and relies solely on testing to discover
1179defects; the other is conducted iteratively and discovers defects as it progresses.
1180The first approach delays most defect correction work to the end of the project, making
1181the costs higher, as noted in Table 3-1. The iterative approach absorbs rework piecemeal
1182over the course of the project, which makes the total cost lower. The data in this table
1183and the next is for purposes of illustration only, but the relative costs of the two general
1184approaches are well supported by the research described earlier in this chapter.
1185The iterative project that abbreviates or eliminates prerequisites will differ in two
1186ways from a sequential project that does the same thing. First, average defect correction
1187costs will be lower because defects will tend to be detected closer to the time
1188they were inserted into the software. However, the defects will still be detected late
1189in each iteration, and correcting them will require parts of the software to be
1190redesigned, recoded, and retested—which makes the defect-correction cost higher
1191than it needs to be.
1192Table 3-3 Effect of Skipping Prerequisites on Sequential and Iterative Projects
1193Approach #1: Sequential
1194Approach Without
1195Prerequisites
1196Approach #2: Iterative
1197Approach Without
1198Prerequisites
1199Project Completion
1200Status Cost of Work
1201Cost of
1202Rework Cost of Work
1203Cost of
1204Rework
120520% $100,000 $0 $100,000 $75,000
120640% $100,000 $0 $100,000 $75,000
120760% $100,000 $0 $100,000 $75,000
120880% $100,000 $0 $100,000 $75,000
1209100% $100,000 $0 $100,000 $75,000
1210End-of-Project
1211Rework $0 $500,000 $0 $0
1212TOTAL $500,000 $500,000 $500,000 $375,000
1213GRAND TOTAL $1,000,000 $875,000
121434 Chapter 3: Measure Twice, Cut Once: Upstream Prerequisites
1215Second, with iterative approaches costs will be absorbed piecemeal, throughout the
1216project, rather than being clustered at the end. When all the dust settles, the total cost
1217will be similar but it won’t seem as high because the price will have been paid in small
1218installments over the course of the project, rather than paid all at once at the end.
1219As Table 3-4 illustrates, a focus on prerequisites can reduce costs regardless of
1220whether you use an iterative or a sequential approach. Iterative approaches are usually
1221a better option for many reasons, but an iterative approach that ignores prerequisites
1222can end up costing significantly more than a sequential project that pays close attention
1223to prerequisites.
1224As Table 3-4 suggested, most projects are neither completely sequential nor completely
1225iterative. It isn’t practical to specify 100 percent of the requirements or design
1226up front, but most projects find value in identifying at least the most critical requirements
1227and architectural elements early.
1228Cross-Reference For details
1229on how to adapt your development
1230approach for programs
1231of different sizes, see
1232Chapter 27, “How Program
1233Size Affects Construction.â€
1234One common rule of thumb is to plan to specify about 80 percent of the requirements
1235up front, allocate time for additional requirements to be specified later, and then practice
1236systematic change control to accept only the most valuable new requirements as
1237the project progresses. Another alternative is to specify only the most important 20
1238percent of the requirements up front and plan to develop the rest of the software in
1239small increments, specifying additional requirements and designs as you go. Figures
12403-2 and 3-3 reflect these different approaches.
1241Table 3-4 Effect of Focusing on Prerequisites on Sequential and Iterative
1242Projects
1243Approach #3: Sequential
1244Approach with Prerequisites
1245Approach #4: Iterative
1246Approach with Prerequisites
1247Project completion
1248status Cost of Work
1249Cost of
1250Rework Cost of Work
1251Cost of
1252Rework
125320% $100,000 $20,000 $100,000 $10,000
125440% $100,000 $20,000 $100,000 $10,000
125560% $100,000 $20,000 $100,000 $10,000
125680% $100,000 $20,000 $100,000 $10,000
1257100% $100,000 $20,000 $100,000 $10,000
1258End-of-Project
1259Rework $0 $0 $0 $0
1260TOTAL $500,000 $100,000 $500,000 $50,000
1261GRAND TOTAL $600,000 $550,000
1262KEY POINT
12633.2 Determine the Kind of Software You’re Working On 35
1264Figure 3-2 Activities will overlap to some degree on most projects, even those that are
1265highly sequential.
1266Figure 3-3 On other projects, activities will overlap for the duration of the project. One key
1267to successful construction is understanding the degree to which prerequisites have been
1268completed and adjusting your approach accordingly.
1269Choosing Between Iterative and Sequential Approaches
1270The extent to which prerequisites need to be satisfied up front will vary with the
1271project type indicated in Table 3-2, project formality, technical environment, staff
1272capabilities, and project business goals. You might choose a more sequential (upfront)
1273approach when
1274â– The requirements are fairly stable.
1275â– The design is straightforward and fairly well understood.
1276â– The development team is familiar with the applications area.
1277Quality Assurance/System Testing
1278Requirements
1279Architecture
1280Detailed Design
1281Construction
1282Time
1283Time
1284Quality Assurance/System Testing
1285Requirements
1286Detailed Design
1287Architecture
1288Detailed Design
1289Construction
129036 Chapter 3: Measure Twice, Cut Once: Upstream Prerequisites
1291â– The project contains little risk.
1292â– Long-term predictability is important.
1293â– The cost of changing requirements, design, and code downstream is likely to be
1294high.
1295You might choose a more iterative (as-you-go) approach when
1296â– The requirements are not well understood or you expect them to be unstable for
1297other reasons.
1298â– The design is complex, challenging, or both.
1299â– The development team is unfamiliar with the applications area.
1300â– The project contains a lot of risk.
1301â– Long-term predictability is not important.
1302â– The cost of changing requirements, design, and code downstream is likely to be
1303low.
1304Software being what it is, iterative approaches are useful much more often than
1305sequential approaches are. You can adapt the prerequisites to your specific project by
1306making them more or less formal and more or less complete, as you see fit. For a
1307detailed discussion of different approaches to large and small projects (also known as
1308the different approaches to formal and informal projects), see Chapter 27.
1309The net impact on construction prerequisites is that you should first determine what
1310construction prerequisites are well suited to your project. Some projects spend too little
1311time on prerequisites, which exposes construction to an unnecessarily high rate of
1312destabilizing changes and prevents the project from making consistent progress.
1313Some projects do too much up front; they doggedly adhere to requirements and plans
1314that have been invalidated by downstream discoveries, and that can also impede
1315progress during construction.
1316Now that you’ve studied Table 3-2 and determined what prerequisites are appropriate
1317for your project, the rest of this chapter describes how to determine whether each specific
1318construction prerequisite has been “prereq’d†or “prewrecked.â€
13193.3 Problem-Definition Prerequisite
1320If the “box†is the boundary
1321of constraints and conditions,
1322then the trick is to find
1323the box.... Don’t think outside
1324the box—find the box.
1325—Andy Hunt and Dave
1326Thomas
1327The first prerequisite you need to fulfill before beginning construction is a clear statement
1328of the problem that the system is supposed to solve. This is sometimes called
1329“product vision,†“vision statement,†“mission statement,†or “product definition.â€
1330Here it’s called “problem definition.†Since this book is about construction, this section
1331doesn’t tell you how to write a problem definition; it tells you how to recognize
1332whether one has been written at all and whether the one that’s written will form a
1333good foundation for construction.
13343.3 Problem-Definition Prerequisite 37
1335A problem definition defines what the problem is without any reference to possible
1336solutions. It’s a simple statement, maybe one or two pages, and it should sound like a
1337problem. The statement “We can’t keep up with orders for the Gigatron†sounds like
1338a problem and is a good problem definition. The statement “We need to optimize our
1339automated data-entry system to keep up with orders for the Gigatron†is a poor problem
1340definition. It doesn’t sound like a problem; it sounds like a solution.
1341As shown in Figure 3-4, problem definition comes before detailed requirements work,
1342which is a more in-depth investigation of the problem.
1343Figure 3-4 The problem definition lays the foundation for the rest of the programming
1344process.
1345The problem definition should be in user language, and the problem should be
1346described from a user’s point of view. It usually should not be stated in technical computer
1347terms. The best solution might not be a computer program. Suppose you need
1348a report that shows your annual profit. You already have computerized reports that
1349show quarterly profits. If you’re locked into the programmer mindset, you’ll reason
1350that adding an annual report to a system that already does quarterly reports should be
1351easy. Then you’ll pay a programmer to write and debug a time-consuming program
1352that calculates annual profits. If you’re not locked into the programmer mindset,
1353you’ll pay your secretary to create the annual figures by taking one minute to add up
1354the quarterly figures on a pocket calculator.
1355The exception to this rule applies when the problem is with the computer: compile
1356times are too slow or the programming tools are buggy. Then it’s appropriate to state
1357the problem in computer or programmer terms.
1358As Figure 3-5 suggests, without a good problem definition, you might put effort into
1359solving the wrong problem.
1360Problem Definition
1361Requirements
1362Architecture
1363Construction
1364System testing
1365Future
1366Improvements
136738 Chapter 3: Measure Twice, Cut Once: Upstream Prerequisites
1368Figure 3-5 Be sure you know what you’re aiming at before you shoot.
1369The penalty for failing to define the problem is that you can waste a lot of time solving
1370the wrong problem. This is a double-barreled penalty because you also don’t solve the
1371right problem.
13723.4 Requirements Prerequisite
1373Requirements describe in detail what a software system is supposed to do, and they
1374are the first step toward a solution. The requirements activity is also known as
1375“requirements development,†“requirements analysis,†“analysis,†“requirements definition,â€
1376“software requirements,†“specification,†“functional spec,†and “spec.â€
1377Why Have Official Requirements?
1378An explicit set of requirements is important for several reasons.
1379Explicit requirements help to ensure that the user rather than the programmer drives
1380the system’s functionality. If the requirements are explicit, the user can review them
1381and agree to them. If they’re not, the programmer usually ends up making requirements
1382decisions during programming. Explicit requirements keep you from guessing
1383what the user wants.
1384Explicit requirements also help to avoid arguments. You decide on the scope of the
1385system before you begin programming. If you have a disagreement with another programmer
1386about what the program is supposed to do, you can resolve it by looking at
1387the written requirements.
1388Paying attention to requirements helps to minimize changes to a system after development
1389begins. If you find a coding error during coding, you change a few lines of code
1390and work goes on. If you find a requirements error during coding, you have to alter
1391the design to meet the changed requirement. You might have to throw away part of the
1392old design, and because it has to accommodate code that’s already written, the new
1393design will take longer than it would have in the first place. You also have to discard
1394KEY POINT
1395KEY POINT
13963.4 Requirements Prerequisite 39
1397code and test cases affected by the requirement change and write new code and test
1398cases. Even code that’s otherwise unaffected must be retested so that you can be sure
1399the changes in other areas haven’t introduced any new errors.
1400As Table 3-1 reported, data from numerous organizations indicates that on large
1401projects an error in requirements detected during the architecture stage is typically 3
1402times as expensive to correct as it would be if it were detected during the requirements
1403stage. If detected during coding, it’s 5–10 times as expensive; during system test, 10
1404times; and post-release, a whopping 10–100 times as expensive as it would be if it were
1405detected during requirements development. On smaller projects with lower administrative
1406costs, the multiplier post-release is closer to 5–10 than 100 (Boehm and Turner
14072004). In either case, it isn’t money you’d want to have taken out of your salary.
1408Specifying requirements adequately is a key to project success, perhaps even more
1409important than effective construction techniques. (See Figure 3-6.) Many good books
1410have been written about how to specify requirements well. Consequently, the next few
1411sections don’t tell you how to do a good job of specifying requirements, they tell you
1412how to determine whether the requirements have been done well and how to make
1413the best of the requirements you have.
1414Figure 3-6 Without good requirements, you can have the right general problem but miss
1415the mark on specific aspects of the problem.
1416The Myth of Stable Requirements
1417Requirements are like water.
1418They’re easier to build on
1419when they’re frozen.
1420—Anonoymous
1421Stable requirements are the holy grail of software development. With stable requirements,
1422a project can proceed from architecture to design to coding to testing in a way
1423that’s orderly, predictable, and calm. This is software heaven! You have predictable
1424expenses, and you never have to worry about a feature costing 100 times as much to
1425implement as it would otherwise because your user didn’t think of it until you were
1426finished debugging.
14271
14282
14293
1430HARD DATA
143140 Chapter 3: Measure Twice, Cut Once: Upstream Prerequisites
1432It’s fine to hope that once your customer has accepted a requirements document, no
1433changes will be needed. On a typical project, however, the customer can’t reliably
1434describe what is needed before the code is written. The problem isn’t that the customers
1435are a lower life form. Just as the more you work with the project, the better you
1436understand it, the more they work with it, the better they understand it. The development
1437process helps customers better understand their own needs, and this is a major
1438source of requirements changes (Curtis, Krasner, and Iscoe 1988; Jones 1998; Wiegers
14392003). A plan to follow the requirements rigidly is actually a plan not to respond
1440to your customer.
1441How much change is typical? Studies at IBM and other companies have found that the
1442average project experiences about a 25 percent change in requirements during development
1443(Boehm 1981, Jones 1994, Jones 2000), which accounts for 70 to 85 percent
1444of the rework on a typical project (Leffingwell 1997, Wiegers 2003).
1445Maybe you think the Pontiac Aztek was the greatest car ever made, belong to the Flat
1446Earth Society, and make a pilgrimage to the alien landing site at Roswell, New Mexico,
1447every four years. If you do, go ahead and believe that requirements won’t change on
1448your projects. If, on the other hand, you’ve stopped believing in Santa Claus and the
1449Tooth Fairy, or at least have stopped admitting it, you can take several steps to minimize
1450the impact of requirements changes.
1451Handling Requirements Changes During Construction
1452Here are several things you can do to make the best of changing requirements during
1453construction:
1454Use the requirements checklist at the end of the section to assess the quality of your
1455requirements If your requirements aren’t good enough, stop work, back up, and
1456make them right before you proceed. Sure, it feels like you’re getting behind if you stop
1457coding at this stage. But if you’re driving from Chicago to Los Angeles, is it a waste of
1458time to stop and look at a road map when you see signs for New York? No. If you’re
1459not heading in the right direction, stop and check your course.
1460Make sure everyone knows the cost of requirements changes Clients get excited
1461when they think of a new feature. In their excitement, their blood thins and runs to
1462their medulla oblongata and they become giddy, forgetting all the meetings you had to
1463discuss requirements, the signing ceremony, and the completed requirements document.
1464The easiest way to handle such feature-intoxicated people is to say, “Gee, that
14651
14662
14673
1468HARD DATA
1469KEY POINT
14703.4 Requirements Prerequisite 41
1471sounds like a great idea. Since it’s not in the requirements document, I’ll work up a
1472revised schedule and cost estimate so that you can decide whether you want to do it
1473now or later.†The words “schedule†and “cost†are more sobering than coffee and a
1474cold shower, and many “must haves†will quickly turn into “nice to haves.â€
1475If your organization isn’t sensitive to the importance of doing requirements first, point
1476out that changes at requirements time are much cheaper than changes later. Use this
1477chapter’s “Utterly Compelling and Foolproof Argument for Doing Prerequisites Before
1478Construction.â€
1479Cross-Reference For details
1480on handling changes to
1481design and code, see Section
148228.2, “Configuration
1483Management.â€
1484Set up a change-control procedure If your client’s excitement persists, consider
1485establishing a formal change-control board to review such proposed changes. It’s all
1486right for customers to change their minds and to realize that they need more capabilities.
1487The problem is their suggesting changes so frequently that you can’t keep up.
1488Having a built-in procedure for controlling changes makes everyone happy. You’re
1489happy because you know that you’ll have to work with changes only at specific times.
1490Your customers are happy because they know that you have a plan for handling their
1491input.
1492Cross-Reference For details
1493on iterative development
1494approaches, see “Iterate†in
1495Section 5.4 and Section 29.3,
1496“Incremental Integration
1497Strategies.â€
1498Use development approaches that accommodate changes Some development
1499approaches maximize your ability to respond to changing requirements. An evolutionary
1500prototyping approach helps you explore a system’s requirements before you send
1501your forces in to build it. Evolutionary delivery is an approach that delivers the system
1502in stages. You can build a little, get a little feedback from your users, adjust your design
1503a little, make a few changes, and build a little more. The key is using short development
1504cycles so that you can respond to your users quickly.
1505Further Reading For details
1506on development approaches
1507that support flexible requirements,
1508see Rapid Development
1509(McConnell 1996).
1510Dump the project If the requirements are especially bad or volatile and none of the
1511suggestions above are workable, cancel the project. Even if you can’t really cancel the
1512project, think about what it would be like to cancel it. Think about how much worse it
1513would have to get before you would cancel it. If there’s a case in which you would dump
1514it, at least ask yourself how much difference there is between your case and that case.
1515Cross-Reference For details
1516on the differences between
1517formal and informal projects
1518(often caused by differences
1519in project size), see Chapter
152027, “How Program Size
1521Affects Construction.â€
1522Keep your eye on the business case for the project Many requirements issues disappear
1523before your eyes when you refer back to the business reason for doing the project.
1524Requirements that seemed like good ideas when considered as “features†can seem like
1525terrible ideas when you evaluate the “incremental business value.†Programmers who
1526remember to consider the business impact of their decisions are worth their weight in
1527gold—although I’ll be happy to receive my commission for this advice in cash.
152842 Chapter 3: Measure Twice, Cut Once: Upstream Prerequisites
1529cc2e.com/0323 Checklist: Requirements
1530The requirements checklist contains a list of questions to ask yourself about
1531your project’s requirements. This book doesn’t tell you how to do good requirements
1532development, and the list won’t tell you how to do one either. Use the list
1533as a sanity check at construction time to determine how solid the ground that
1534you’re standing on is—where you are on the requirements Richter scale.
1535Not all of the checklist questions will apply to your project. If you’re working on
1536an informal project, you’ll find some that you don’t even need to think about.
1537You’ll find others that you need to think about but don’t need to answer formally.
1538If you’re working on a large, formal project, however, you may need to
1539consider every one.
1540Specific Functional Requirements
1541â‘ Are all the inputs to the system specified, including their source, accuracy,
1542range of values, and frequency?
1543â‘ Are all the outputs from the system specified, including their destination,
1544accuracy, range of values, frequency, and format?
1545â‘ Are all output formats specified for Web pages, reports, and so on?
1546â‘ Are all the external hardware and software interfaces specified?
1547â‘ Are all the external communication interfaces specified, including handshaking,
1548error-checking, and communication protocols?
1549â‘ Are all the tasks the user wants to perform specified?
1550â‘ Is the data used in each task and the data resulting from each task specified?
1551Specific Nonfunctional (Quality) Requirements
1552①Is the expected response time, from the user’s point of view, specified for
1553all necessary operations?
1554â‘ Are other timing considerations specified, such as processing time, datatransfer
1555rate, and system throughput?
1556â‘ Is the level of security specified?
1557â‘ Is the reliability specified, including the consequences of software failure,
1558the vital information that needs to be protected from failure, and the strategy
1559for error detection and recovery?
1560â‘ Are minimum machine memory and free disk space specified?
1561â‘ Is the maintainability of the system specified, including its ability to adapt
1562to changes in specific functionality, changes in the operating environment,
1563and changes in its interfaces with other software?
1564â‘ Is the definition of success included? Of failure?
15653.5 Architecture Prerequisite 43
1566Requirements Quality
1567①Are the requirements written in the user’s language? Do the users think
1568so?
1569â‘ Does each requirement avoid conflicts with other requirements?
1570①Are acceptable tradeoffs between competing attributes specified—for
1571example, between robustness and correctness?
1572â‘ Do the requirements avoid specifying the design?
1573â‘ Are the requirements at a fairly consistent level of detail? Should any
1574requirement be specified in more detail? Should any requirement be specified
1575in less detail?
1576â‘ Are the requirements clear enough to be turned over to an independent
1577group for construction and still be understood? Do the developers think
1578so?
1579â‘ Is each item relevant to the problem and its solution? Can each item be
1580traced to its origin in the problem environment?
1581â‘ Is each requirement testable? Will it be possible for independent testing to
1582determine whether each requirement has been satisfied?
1583â‘ Are all possible changes to the requirements specified, including the likelihood
1584of each change?
1585Requirements Completeness
1586①Where information isn’t available before development begins, are the
1587areas of incompleteness specified?
1588â‘ Are the requirements complete in the sense that if the product satisfies
1589every requirement, it will be acceptable?
1590â‘ Are you comfortable with all the requirements? Have you eliminated
1591requirements that are impossible to implement and included just to
1592appease your customer or your boss?
15933.5 Architecture Prerequisite
1594Cross-Reference For more
1595information on design at all
1596levels, see Chapters 5
1597through 9.
1598Software architecture is the high-level part of software design, the frame that holds the
1599more detailed parts of the design (Buschman et al. 1996; Fowler 2002; Bass Clements,
1600Kazman 2003; Clements et al. 2003). Architecture is also known as “system architecture,â€
1601“high-level design,†and “top-level design.†Typically, the architecture is
1602described in a single document referred to as the “architecture specification†or “toplevel
1603design.†Some people make a distinction between architecture and high-level
160444 Chapter 3: Measure Twice, Cut Once: Upstream Prerequisites
1605design—architecture refers to design constraints that apply systemwide, whereas highlevel
1606design refers to design constraints that apply at the subsystem or multiple-class
1607level, but not necessarily systemwide.
1608Because this book is about construction, this section doesn’t tell you how to develop
1609a software architecture; it focuses on how to determine the quality of an existing architecture.
1610Because architecture is one step closer to construction than requirements,
1611however, the discussion of architecture is more detailed than the discussion of
1612requirements.
1613Why have architecture as a prerequisite? Because the quality of the architecture determines
1614the conceptual integrity of the system. That in turn determines the ultimate
1615quality of the system. A well-thought-out architecture provides the structure needed to
1616maintain a system’s conceptual integrity from the top levels down to the bottom. It
1617provides guidance to programmers—at a level of detail appropriate to the skills of the
1618programmers and to the job at hand. It partitions the work so that multiple developers
1619or multiple development teams can work independently.
1620Good architecture makes construction easy. Bad architecture makes construction
1621almost impossible. Figure 3-7 illustrates another problem with bad architecture.
1622Figure 3-7 Without good software architecture, you may have the right problem but the
1623wrong solution. It may be impossible to have successful construction.
1624Architectural changes are expensive to make during construction or later. The time
1625needed to fix an error in a software architecture is on the same order as that needed to
1626fix a requirements error—that is, more than that needed to fix a coding error (Basili
1627and Perricone 1984, Willis 1998). Architecture changes are like requirements changes
1628in that seemingly small changes can be far-reaching. Whether the architectural
1629changes arise from the need to fix errors or the need to make improvements, the earlier
1630you can identify the changes, the better.
1631KEY POINT
16321
16332
16343
1635HARD DATA
16363.5 Architecture Prerequisite 45
1637Typical Architectural Components
1638Cross-Reference For details
1639on lower-level program
1640design, see Chapters 5
1641through 9.
1642Many components are common to good system architectures. If you’re building the
1643whole system yourself, your work on the architecture will overlap your work on the
1644more detailed design. In such a case, you should at least think about each architectural
1645component. If you’re working on a system that was architected by someone else,
1646you should be able to find the important components without a bloodhound, a deerstalker
1647cap, and a magnifying glass. In either case, here are the architectural components
1648to consider.
1649Program Organization
1650If you can’t explain something
1651to a six-year-old, you
1652really don’t understand it
1653yourself.
1654—Albert Einstein
1655A system architecture first needs an overview that describes the system in broad
1656terms. Without such an overview, you’ll have a hard time building a coherent picture
1657from a thousand details or even a dozen individual classes. If the system were a little
165812-piece jigsaw puzzle, your one-year-old could solve it between spoonfuls of strained
1659asparagus. A puzzle of 12 subsystems is harder to put together, and if you can’t put it
1660together, you won’t understand how a class you’re developing contributes to the system.
1661In the architecture, you should find evidence that alternatives to the final organization
1662were considered and find the reasons for choosing the final organization over its alternatives.
1663It’s frustrating to work on a class when it seems as if the class’s role in the system
1664has not been clearly conceived. By describing the organizational alternatives, the architecture
1665provides the rationale for the system organization and shows that each class has
1666been carefully considered. One review of design practices found that the design rationale
1667is at least as important for maintenance as the design itself (Rombach 1990).
1668Cross-Reference For details
1669on different size building
1670blocks in design, see “Levels
1671of Design†in Section 5.2.
1672The architecture should define the major building blocks in a program. Depending on
1673the size of the program, each building block might be a single class or it might be a
1674subsystem consisting of many classes. Each building block is a class, or it’s a collection
1675of classes or routines that work together on high-level functions such as interacting
1676with the user, displaying Web pages, interpreting commands, encapsulating
1677business rules, or accessing data. Every feature listed in the requirements should be
1678covered by at least one building block. If a function is claimed by two or more building
1679blocks, their claims should cooperate, not conflict.
1680Cross-Reference Minimizing
1681what each building block
1682knows about other building
1683blocks is a key part of information
1684hiding. For details,
1685see “Hide Secrets (Information
1686Hiding)†in Section 5.3.
1687What each building block is responsible for should be well defined. A building block
1688should have one area of responsibility, and it should know as little as possible about
1689other building blocks’ areas of responsibility. By minimizing what each building block
1690knows about the other building blocks, you localize information about the design into
1691single building blocks.
169246 Chapter 3: Measure Twice, Cut Once: Upstream Prerequisites
1693The communication rules for each building block should be well defined. The architecture
1694should describe which other building blocks the building block can use
1695directly, which it can use indirectly, and which it shouldn’t use at all.
1696Major Classes
1697Cross-Reference For details
1698on class design, see Chapter
16996, “Working Classes.â€
1700The architecture should specify the major classes to be used. It should identify the
1701responsibilities of each major class and how the class will interact with other classes.
1702It should include descriptions of the class hierarchies, of state transitions, and of
1703object persistence. If the system is large enough, it should describe how classes are
1704organized into subsystems.
1705The architecture should describe other class designs that were considered and give
1706reasons for preferring the organization that was chosen. The architecture doesn’t need
1707to specify every class in the system. Aim for the 80/20 rule: specify the 20 percent of
1708the classes that make up 80 percent of the system’s behavior (Jacobsen, Booch, and
1709Rumbaugh 1999; Kruchten 2000).
1710Data Design
1711Cross-Reference For details
1712on working with variables,
1713see Chapters 10 through 13.
1714The architecture should describe the major files and table designs to be used. It
1715should describe alternatives that were considered and justify the choices that were
1716made. If the application maintains a list of customer IDs and the architects have chosen
1717to represent the list of IDs using a sequential-access list, the document should
1718explain why a sequential-access list is better than a random-access list, stack, or hash
1719table. During construction, such information gives you insight into the minds of the
1720architects. During maintenance, the same insight is an invaluable aid. Without it,
1721you’re watching a foreign movie with no subtitles.
1722Data should normally be accessed directly by only one subsystem or class, except
1723through access classes or routines that allow access to the data in controlled and
1724abstract ways. This is explained in more detail in “Hide Secrets (Information Hiding)â€
1725in Section 5.3.
1726The architecture should specify the high-level organization and contents of any databases
1727used. The architecture should explain why a single database is preferable to
1728multiple databases (or vice versa), explain why a database is preferable to flat files,
1729identify possible interactions with other programs that access the same data, explain
1730what views have been created on the data, and so on.
1731Business Rules
1732If the architecture depends on specific business rules, it should identify them and
1733describe the impact the rules have on the system’s design. For example, suppose the
1734system is required to follow a business rule that customer information should be no
17353.5 Architecture Prerequisite 47
1736more than 30 seconds out of date. In that case, the impact that rule has on the architecture’s
1737approach to keeping customer information up to date and synchronized
1738should be described.
1739User Interface Design
1740The user interface is often specified at requirements time. If it isn’t, it should be specified
1741in the software architecture. The architecture should specify major elements of
1742Web page formats, GUIs, command line interfaces, and so on. Careful architecture of
1743the user interface makes the difference between a well-liked program and one that’s
1744never used.
1745The architecture should be modularized so that a new user interface can be substituted
1746without affecting the business rules and output parts of the program. For example,
1747the architecture should make it fairly easy to lop off a group of interactive interface
1748classes and plug in a group of command line classes. This ability is often useful, especially
1749since command line interfaces are convenient for software testing at the unit or
1750subsystem level.
1751cc2e.com/0393 The design of user interfaces deserves its own book-length discussion but is outside
1752the scope of this book.
1753Resource Management
1754The architecture should describe a plan for managing scarce resources such as database
1755connections, threads, and handles. Memory management is another important
1756area for the architecture to treat in memory-constrained applications areas such as
1757driver development and embedded systems. The architecture should estimate the
1758resources used for nominal and extreme cases. In a simple case, the estimates should
1759show that the resources needed are well within the capabilities of the intended implementation
1760environment. In a more complex case, the application might be required to
1761more actively manage its own resources. If it is, the resource manager should be architected
1762as carefully as any other part of the system.
1763cc2e.com/0330 Security
1764Further Reading For an
1765excellent discussion of software
1766security, see Writing
1767Secure Code, 2d Ed. (Howard
1768and LeBlanc 2003) as well as
1769the January 2002 issue of
1770IEEE Software.
1771The architecture should describe the approach to design-level and code-level security. If a
1772threat model has not previously been built, it should be built at architecture time. Coding
1773guidelines should be developed with security implications in mind, including
1774approaches to handling buffers, rules for handling untrusted data (data input from users,
1775cookies, configuration data, and other external interfaces), encryption, level of detail contained
1776in error messages, protecting secret data that’s in memory, and other issues.
177748 Chapter 3: Measure Twice, Cut Once: Upstream Prerequisites
1778Performance
1779Further Reading For additional
1780information on designing
1781systems for performance,
1782see Connie Smith’s Performance
1783Engineering of
1784Software Systems (1990).
1785If performance is a concern, performance goals should be specified in the requirements.
1786Performance goals can include resource use, in which case the goals should
1787also specify priorities among resources, including speed vs. memory vs. cost.
1788The architecture should provide estimates and explain why the architects believe the
1789goals are achievable. If certain areas are at risk of failing to meet their goals, the architecture
1790should say so. If certain areas require the use of specific algorithms or data
1791types to meet their performance goals, the architecture should say that. The architecture
1792can also include space and time budgets for each class or object.
1793Scalability
1794Scalability is the ability of a system to grow to meet future demands. The architecture
1795should describe how the system will address growth in number of users, number of
1796servers, number of network nodes, number of database records, size of database
1797records, transaction volume, and so on. If the system is not expected to grow and scalability
1798is not an issue, the architecture should make that assumption explicit.
1799Interoperability
1800If the system is expected to share data or resources with other software or hardware,
1801the architecture should describe how that will be accomplished.
1802Internationalization/Localization
1803“Internationalization†is the technical activity of preparing a program to support multiple
1804locales. Internationalization is often known as “I18n†because the first and last
1805characters in “internationalization†are “I†and “N†and because there are 18 letters in
1806the middle of the word. “Localization†(known as “L10n†for the same reason) is the
1807activity of translating a program to support a specific local language.
1808Internationalization issues deserve attention in the architecture for an interactive system.
1809Most interactive systems contain dozens or hundreds of prompts, status displays,
1810help messages, error messages, and so on. Resources used by the strings should
1811be estimated. If the program is to be used commercially, the architecture should show
1812that the typical string and character-set issues have been considered, including character
1813set used (ASCII, DBCS, EBCDIC, MBCS, Unicode, ISO 8859, and so on), kinds
1814of strings used (C strings, Visual Basic strings, and so on), maintaining the strings
1815without changing code, and translating the strings into foreign languages with minimal
1816impact on the code and the user interface. The architecture can decide to use
1817strings in line in the code where they’re needed, keep the strings in a class and reference
1818them through the class interface, or store the strings in a resource file. The architecture
1819should explain which option was chosen and why.
18203.5 Architecture Prerequisite 49
1821Input/Output
1822Input/output (I/O) is another area that deserves attention in the architecture. The
1823architecture should specify a look-ahead, look-behind, or just-in-time reading scheme.
1824And it should describe the level at which I/O errors are detected: at the field, record,
1825stream, or file level.
1826Error Processing
1827Error processing is turning out to be one of the thorniest problems of modern computer
1828science, and you can’t afford to deal with it haphazardly. Some people have estimated
1829that as much as 90 percent of a program’s code is written for exceptional, errorprocessing
1830cases or housekeeping, implying that only 10 percent is written for nominal
1831cases (Shaw in Bentley 1982). With so much code dedicated to handling errors, a
1832strategy for handling them consistently should be spelled out in the architecture.
1833Error handling is often treated as a coding-convention-level issue, if it’s treated at all.
1834But because it has systemwide implications, it is best treated at the architectural level.
1835Here are some questions to consider:
1836â– Is error processing corrective or merely detective? If corrective, the program can
1837attempt to recover from errors. If it’s merely detective, the program can continue
1838processing as if nothing had happened, or it can quit. In either case, it should
1839notify the user that it detected an error.
1840■Is error detection active or passive? The system can actively anticipate errors—for
1841example, by checking user input for validity—or it can passively respond to them
1842only when it can’t avoid them—for example, when a combination of user input
1843produces a numeric overflow. It can clear the way or clean up the mess. Again, in
1844either case, the choice has user-interface implications.
1845â– How does the program propagate errors? Once it detects an error, it can immediately
1846discard the data that caused the error, it can treat the error as an error
1847and enter an error-processing state, or it can wait until all processing is complete
1848and notify the user that errors were detected (somewhere).
1849â– What are the conventions for handling error messages? If the architecture
1850doesn’t specify a single, consistent strategy, the user interface will appear to be a
1851confusing macaroni-and-dried-bean collage of different interfaces in different
1852parts of the program. To avoid such an appearance, the architecture should
1853establish conventions for error messages.
1854â– How will exceptions be handled? The architecture should address when the
1855code can throw exceptions, where they will be caught, how they will be logged,
1856how they will be documented, and so on.
18571
18582
18593
1860HARD DATA
186150 Chapter 3: Measure Twice, Cut Once: Upstream Prerequisites
1862Cross-Reference A consistent
1863method of handling bad
1864parameters is another aspect
1865of error-processing strategy
1866that should be addressed
1867architecturally. For examples,
1868see Chapter 8, “Defensive
1869Programming.â€
1870â– Inside the program, at what level are errors handled? You can handle them at
1871the point of detection, pass them off to an error-handling class, or pass them up
1872the call chain.
1873â– What is the level of responsibility of each class for validating its input data? Is
1874each class responsible for validating its own data, or is there a group of classes
1875responsible for validating the system’s data? Can classes at any level assume that
1876the data they’re receiving is clean?
1877■Do you want to use your environment’s built-in exception-handling mechanism
1878or build your own? The fact that an environment has a particular error-handling
1879approach doesn’t mean that it’s the best approach for your requirements.
1880Fault Tolerance
1881Further Reading For a good
1882introduction to fault tolerance,
1883see the July 2001 issue
1884of IEEE Software. In addition
1885to providing a good introduction,
1886the articles cite
1887many key books and key
1888articles on the topic.
1889The architecture should also indicate the kind of fault tolerance expected. Fault tolerance
1890is a collection of techniques that increase a system’s reliability by detecting
1891errors, recovering from them if possible, and containing their bad effects if not.
1892For example, a system could make the computation of the square root of a number
1893fault tolerant in any of several ways:
1894â– The system might back up and try again when it detects a fault. If the first
1895answer is wrong, it would back up to a point at which it knew everything was all
1896right and continue from there.
1897â– The system might have auxiliary code to use if it detects a fault in the primary
1898code. In the example, if the first answer appears to be wrong, the system
1899switches over to an alternative square-root routine and uses it instead.
1900â– The system might use a voting algorithm. It might have three square-root classes
1901that each use a different method. Each class computes the square root, and then
1902the system compares the results. Depending on the kind of fault tolerance built
1903into the system, it then uses the mean, the median, or the mode of the three
1904results.
1905â– The system might replace the erroneous value with a phony value that it knows
1906to have a benign effect on the rest of the system.
1907Other fault-tolerance approaches include having the system change to a state of partial
1908operation or a state of degraded functionality when it detects an error. It can shut
1909itself down or automatically restart itself. These examples are necessarily simplistic.
1910Fault tolerance is a fascinating and complex subject—unfortunately, it’s one that’s outside
1911the scope of this book.
19123.5 Architecture Prerequisite 51
1913Architectural Feasibility
1914The designers might have concerns about a system’s ability to meet its performance
1915targets, work within resource limitations, or be adequately supported by the implementation
1916environments. The architecture should demonstrate that the system is
1917technically feasible. If infeasibility in any area could render the project unworkable,
1918the architecture should indicate how those issues have been investigated—through
1919proof-of-concept prototypes, research, or other means. These risks should be resolved
1920before full-scale construction begins.
1921Overengineering
1922Robustness is the ability of a system to continue to run after it detects an error. Often
1923an architecture specifies a more robust system than that specified by the requirements.
1924One reason is that a system composed of many parts that are minimally robust
1925might be less robust than is required overall. In software, the chain isn’t as strong as
1926its weakest link; it’s as weak as all the weak links multiplied together. The architecture
1927should clearly indicate whether programmers should err on the side of overengineering
1928or on the side of doing the simplest thing that works.
1929Specifying an approach to overengineering is particularly important because many
1930programmers overengineer their classes automatically, out of a sense of professional
1931pride. By setting expectations explicitly in the architecture, you can avoid the phenomenon
1932in which some classes are exceptionally robust and others are barely adequate.
1933Buy-vs.-Build Decisions
1934Cross-Reference For a list of
1935kinds of commercially available
1936software components
1937and libraries, see “Code
1938Libraries†in Section 30.3.
1939The most radical solution to building software is not to build it at all—to buy it instead
1940or to download open-source software for free. You can buy GUI controls, database
1941managers, image processors, graphics and charting components, Internet communications
1942components, security and encryption components, spreadsheet tools, textprocessing
1943tools—the list is nearly endless. One of the greatest advantages of programming
1944in modern GUI environments is the amount of functionality you get automatically:
1945graphics classes, dialog box managers, keyboard and mouse handlers, code that
1946works automatically with any printer or monitor, and so on.
1947If the architecture isn’t using off-the-shelf components, it should explain the ways
1948in which it expects custom-built components to surpass ready-made libraries and
1949components.
195052 Chapter 3: Measure Twice, Cut Once: Upstream Prerequisites
1951Reuse Decisions
1952If the plan calls for using preexisting software, test cases, data formats, or other materials,
1953the architecture should explain how the reused software will be made to conform
1954to the other architectural goals—if it will be made to conform.
1955Change Strategy
1956Cross-Reference For details
1957on handling changes systematically,
1958see Section 28.2,
1959“Configuration Management.â€
1960Because building a software product is a learning process for both the programmers
1961and the users, the product is likely to change throughout its development. Changes
1962arise from volatile data types and file formats, changed functionality, new features, and
1963so on. The changes can be new capabilities likely to result from planned enhancements,
1964or they can be capabilities that didn’t make it into the first version of the system.
1965Consequently, one of the major challenges facing a software architect is making
1966the architecture flexible enough to accommodate likely changes.
1967Design bugs are often subtle
1968and occur by evolution with
1969early assumptions being forgotten
1970as new features or
1971uses are added to a system.
1972—Fernando J. Corbató
1973The architecture should clearly describe a strategy for handling changes. The architecture
1974should show that possible enhancements have been considered and that the
1975enhancements most likely are also the easiest to implement. If changes are likely in
1976input or output formats, style of user interaction, or processing requirements, the
1977architecture should show that the changes have all been anticipated and that the
1978effects of any single change will be limited to a small number of classes. The architecture’s
1979plan for changes can be as simple as one to put version numbers in data files,
1980reserve fields for future use, or design files so that you can add new tables. If a code
1981generator is being used, the architecture should show that the anticipated changes are
1982within the capabilities of the code generator.
1983Cross-Reference For a full
1984explanation of delaying
1985commitment, see “Choose
1986Binding Time Consciously†in
1987Section 5.3.
1988The architecture should indicate the strategies that are used to delay commitment. For
1989example, the architecture might specify that a table-driven technique be used rather
1990than hard-coded if tests. It might specify that data for the table is to be kept in an external
1991file rather than coded inside the program, thus allowing changes in the program
1992without recompiling.
1993General Architectural Quality
1994Cross-Reference For more
1995information about how quality
1996attributes interact, see
1997Section 20.1, “Characteristics
1998of Software Quality.â€
1999A good architecture specification is characterized by discussions of the classes in the
2000system, of the information that’s hidden in each class, and of the rationales for including
2001and excluding all possible design alternatives.
2002The architecture should be a polished conceptual whole with few ad hoc additions.
2003The central thesis of the most popular software-engineering book ever, The Mythical
2004Man-Month, is that the essential problem with large systems is maintaining their conceptual
2005integrity (Brooks 1995). A good architecture should fit the problem. When
2006you look at the architecture, you should be pleased by how natural and easy the solution
2007seems. It shouldn’t look as if the problem and the architecture have been forced
2008together with duct tape.
20093.5 Architecture Prerequisite 53
2010You might know of ways in which the architecture was changed during its development.
2011Each change should fit in cleanly with the overall concept. The architecture
2012shouldn’t look like a U.S. Congress appropriations bill complete with pork-barrel,
2013boondoggle riders for each representative’s home district.
2014The architecture’s objectives should be clearly stated. A design for a system with a primary
2015goal of modifiability will be different from one with a goal of uncompromised
2016performance, even if both systems have the same function.
2017The architecture should describe the motivations for all major decisions. Be wary of
2018“we’ve always done it that way†justifications. One story goes that Beth wanted to
2019cook a pot roast according to an award-winning pot roast recipe handed down in her
2020husband’s family. Her husband, Abdul, said that his mother had taught him to sprinkle
2021it with salt and pepper, cut both ends off, put it in the pan, cover it, and cook it.
2022Beth asked, “Why do you cut both ends off?†Abdul said, “I don’t know. I’ve always
2023done it that way. Let me ask my mother.†He called her, and she said, “I don’t know.
2024I’ve always done it that way. Let me ask your grandmother.†She called his grandmother,
2025who said, “I don’t know why you do it that way. I did it that way because it
2026was too big to fit in my pan.â€
2027Good software architecture is largely machine- and language-independent. Admittedly,
2028you can’t ignore the construction environment. By being as independent of the
2029environment as possible, however, you avoid the temptation to overarchitect the system
2030or to do a job that you can do better during construction. If the purpose of a program
2031is to exercise a specific machine or language, this guideline doesn’t apply.
2032The architecture should tread the line between underspecifying and overspecifying
2033the system. No part of the architecture should receive more attention than it deserves,
2034or be overdesigned. Designers shouldn’t pay attention to one part at the expense of
2035another. The architecture should address all requirements without gold-plating (without
2036containing elements that are not required).
2037The architecture should explicitly identify risky areas. It should explain why they’re
2038risky and what steps have been taken to minimize the risk.
2039The architecture should contain multiple views. Plans for a house will include elevations,
2040floor plan, framing plan, electrical diagrams, and other views of the house. Software
2041architecture descriptions also benefit from providing different views of the
2042system that flush out errors and inconsistencies and help programmers fully understand
2043the system’s design (Kruchten 1995).
2044Finally, you shouldn’t be uneasy about any parts of the architecture. It shouldn’t contain
2045anything just to please the boss. It shouldn’t contain anything that’s hard for you
2046to understand. You’re the one who’ll implement it; if it doesn’t make sense to you, how
2047can you implement it?
204854 Chapter 3: Measure Twice, Cut Once: Upstream Prerequisites
2049cc2e.com/0337 Checklist: Architecture
2050Here’s a list of issues that a good architecture should address. The list isn’t
2051intended to be a comprehensive guide to architecture but to be a pragmatic way
2052of evaluating the nutritional content of what you get at the programmer’s end of
2053the software food chain. Use this checklist as a starting point for your own
2054checklist. As with the requirements checklist, if you’re working on an informal
2055project, you’ll find some items that you don’t even need to think about. If you’re
2056working on a larger project, most of the items will be useful.
2057Specific Architectural Topics
2058â‘ Is the overall organization of the program clear, including a good architectural
2059overview and justification?
2060â‘ Are major building blocks well defined, including their areas of responsibility
2061and their interfaces to other building blocks?
2062â‘ Are all the functions listed in the requirements covered sensibly, by neither
2063too many nor too few building blocks?
2064â‘ Are the most critical classes described and justified?
2065â‘ Is the data design described and justified?
2066â‘ Is the database organization and content specified?
2067â‘ Are all key business rules identified and their impact on the system
2068described?
2069â‘ Is a strategy for the user interface design described?
2070①Is the user interface modularized so that changes in it won’t affect the rest
2071of the program?
2072â‘ Is a strategy for handling I/O described and justified?
2073â‘ Are resource-use estimates and a strategy for resource management
2074described and justified for scarce resources like threads, database connections,
2075handles, network bandwidth, and so on?
2076①Are the architecture’s security requirements described?
2077â‘ Does the architecture set space and speed budgets for each class, subsystem,
2078or functionality area?
2079â‘ Does the architecture describe how scalability will be achieved?
2080â‘ Does the architecture address interoperability?
2081â‘ Is a strategy for internationalization/localization described?
2082â‘ Is a coherent error-handling strategy provided?
2083â‘ Is the approach to fault tolerance defined (if any is needed)?
20843.6 Amount of Time to Spend on Upstream Prerequisites 55
2085â‘ Has technical feasibility of all parts of the system been established?
2086â‘ Is an approach to overengineering specified?
2087â‘ Are necessary buy-vs.-build decisions included?
2088â‘ Does the architecture describe how reused code will be made to conform
2089to other architectural objectives?
2090â‘ Is the architecture designed to accommodate likely changes?
2091General Architectural Quality
2092â‘ Does the architecture account for all the requirements?
2093â‘ Is any part overarchitected or underarchitected? Are expectations in this
2094area set out explicitly?
2095â‘ Does the whole architecture hang together conceptually?
2096â‘ Is the top-level design independent of the machine and language that will
2097be used to implement it?
2098â‘ Are the motivations for all major decisions provided?
2099â‘ Are you, as a programmer who will implement the system, comfortable
2100with the architecture?
21013.6 Amount of Time to Spend on Upstream Prerequisites
2102Cross-Reference The
2103amount of time you spend
2104on prerequisites will depend
2105on your project type. For
2106details on adapting prerequisites
2107to your specific
2108project, see Section 3.2,
2109“Determine the Kind of Software
2110You’re Working On,â€
2111earlier in this chapter.
2112The amount of time to spend on problem definition, requirements, and software architecture
2113varies according to the needs of your project. Generally, a well-run project devotes
2114about 10 to 20 percent of its effort and about 20 to 30 percent of its schedule to requirements,
2115architecture, and up-front planning (McConnell 1998, Kruchten 2000). These figures
2116don’t include time for detailed design—that’s part of construction.
2117If requirements are unstable and you’re working on a large, formal project, you’ll probably
2118have to work with a requirements analyst to resolve requirements problems that
2119are identified early in construction. Allow time to consult with the requirements analyst
2120and for the requirements analyst to revise the requirements before you’ll have a
2121workable version of the requirements.
2122If requirements are unstable and you’re working on a small, informal project, you’ll probably
2123need to resolve requirements issues yourself. Allow time for defining the requirements
2124well enough that their volatility will have a minimal impact on construction.
212556 Chapter 3: Measure Twice, Cut Once: Upstream Prerequisites
2126Cross-Reference For
2127approaches to handling
2128changing requirements, see
2129“Handling Requirements
2130Changes During Constructionâ€
2131in Section 3.4, earlier in
2132this chapter.
2133If the requirements are unstable on any project—formal or informal—treat requirements
2134work as its own project. Estimate the time for the rest of the project after you’ve
2135finished the requirements. This is a sensible approach since no one can reasonably
2136expect you to estimate your schedule before you know what you’re building. It’s as if
2137you were a contractor called to work on a house. Your customer says, “What will it cost
2138to do the work?†You reasonably ask, “What do you want me to do?†Your customer
2139says, “I can’t tell you, but how much will it cost?†You reasonably thank the customer
2140for wasting your time and go home.
2141With a building, it’s clear that it’s unreasonable for clients to ask for a bid before telling
2142you what you’re going to build. Your clients wouldn’t want you to show up with
2143wood, hammer, and nails and start spending their money before the architect had finished
2144the blueprints. People tend to understand software development less than they
2145understand two-by-fours and sheetrock, however, so the clients you work with might
2146not immediately understand why you want to plan requirements development as a
2147separate project. You might need to explain your reasoning to them.
2148When allocating time for software architecture, use an approach similar to the one for
2149requirements development. If the software is a kind that you haven’t worked with
2150before, allow more time for the uncertainty of designing in a new area. Ensure that the
2151time you need to create a good architecture won’t take away from the time you need
2152for good work in other areas. If necessary, plan the architecture work as a separate
2153project, too.
2154Additional Resources
2155cc2e.com/0344 Following are more resources on requirements:
2156cc2e.com/0351 Requirements
2157Here are a few books that give much more detail on requirements development:
2158Wiegers, Karl. Software Requirements, 2d ed. Redmond, WA: Microsoft Press, 2003.
2159This is a practical, practitioner-focused book that describes the nuts and bolts of
2160requirements activities, including requirements elicitation, requirements analysis,
2161requirements specification, requirements validation, and requirements management.
2162Robertson, Suzanne and James Robertson. Mastering the Requirements Process. Reading,
2163MA: Addison-Wesley, 1999. This is a good alternative to Wiegers’ book for the
2164more advanced requirements practitioner.
2165cc2e.com/0358
2166Gilb, Tom. Competitive Engineering. Reading, MA: Addison-Wesley, 2004. This book
2167describes Gilb’s requirements language, known as “Planguage.†The book covers
2168Gilb’s specific approach to requirements engineering, design and design evaluation,
2169and evolutionary project management. This book can be downloaded from Gilb’s
2170website at www.gilb.com.
2171Additional Resources 57
2172IEEE Std 830-1998. IEEE Recommended Practice for Software Requirements Specifications.
2173Los Alamitos, CA: IEEE Computer Society Press. This document is the IEEE-ANSI
2174guide for writing software-requirements specifications. It describes what should be
2175included in the specification document and shows several alternative outlines for one.
2176cc2e.com/0365
2177Abran, Alain, et al. Swebok: Guide to the Software Engineering Body of Knowledge. Los
2178Alamitos, CA: IEEE Computer Society Press, 2001. This contains a detailed description
2179of the body of software-requirements knowledge. It can also be downloaded from
2180www.swebok.org.
2181Other good alternatives include the following:
2182Lauesen, Soren. Software Requirements: Styles and Techniques. Boston, MA: Addison-
2183Wesley, 2002.
2184Kovitz, Benjamin L. Practical Software Requirements: A Manual of Content and Style.
2185Manning Publications Company, 1998.
2186Cockburn, Alistair. Writing Effective Use Cases. Boston, MA: Addison-Wesley, 2000.
2187cc2e.com/0372 Software Architecture
2188Numerous books on software architecture have been published in the past few years.
2189Here are some of the best:
2190Bass, Len, Paul Clements, and Rick Kazman. Software Architecture in Practice, 2d ed.
2191Boston, MA: Addison-Wesley, 2003.
2192Buschman, Frank, et al. Pattern-Oriented Software Architecture, Volume 1: A System of
2193Patterns. New York, NY: John Wiley & Sons, 1996.
2194Clements, Paul, ed. Documenting Software Architectures: Views and Beyond. Boston, MA:
2195Addison-Wesley, 2003.
2196Clements, Paul, Rick Kazman, and Mark Klein. Evaluating Software Architectures: Methods
2197and Case Studies. Boston, MA: Addison-Wesley, 2002.
2198Fowler, Martin. Patterns of Enterprise Application Architecture. Boston, MA: Addison-
2199Wesley, 2002.
2200Jacobson, Ivar, Grady Booch, and James Rumbaugh. The Unified Software Development
2201Process. Reading, MA: Addison-Wesley, 1999.
2202IEEE Std 1471-2000. Recommended Practice for Architectural Description of Software-
2203Intensive Systems. Los Alamitos, CA: IEEE Computer Society Press. This document is
2204the IEEE-ANSI guide for creating software-architecture specifications.
220558 Chapter 3: Measure Twice, Cut Once: Upstream Prerequisites
2206cc2e.com/0379 General Software-Development Approaches
2207Many books are available that map out different approaches to conducting a software
2208project. Some are more sequential, and some are more iterative.
2209McConnell, Steve. Software Project Survival Guide. Redmond, WA: Microsoft Press,
22101998. This book presents one particular way to conduct a project. The approach presented
2211emphasizes deliberate up-front planning, requirements development, and
2212architecture work followed by careful project execution. It provides long-range predictability
2213of costs and schedules, high quality, and a moderate amount of flexibility.
2214Kruchten, Philippe. The Rational Unified Process: An Introduction, 2d ed. Reading, MA:
2215Addison-Wesley, 2000. This book presents a project approach that is “architecturecentric
2216and use-case driven.†Like Software Project Survival Guide, it focuses on up-front
2217work that provides good long-range predictability of costs and schedules, high quality,
2218and moderate flexibility. This book’s approach requires somewhat more sophisticated
2219use than the approaches described in Software Project Survival Guide and Extreme Programming
2220Explained: Embrace Change.
2221Jacobson, Ivar, Grady Booch, and James Rumbaugh. The Unified Software Development
2222Process. Reading, MA: Addison-Wesley, 1999. This book is a more in-depth treatment
2223of the topics covered in The Rational Unified Process: An Introduction, 2d ed.
2224Beck, Kent. Extreme Programming Explained: Embrace Change. Reading, MA: Addison-
2225Wesley, 2000. Beck describes a highly iterative approach that focuses on developing
2226requirements and designs iteratively, in conjunction with construction. The Extreme
2227Programming approach offers little long-range predictability but provides a high
2228degree of flexibility.
2229Gilb, Tom. Principles of Software Engineering Management. Wokingham, England:
2230Addison-Wesley, 1988. Gilb’s approach explores critical planning, requirements, and
2231architecture issues early in a project and then continuously adapts the project plans as
2232the project progresses. This approach provides a combination of long-range predictability,
2233high quality, and a high degree of flexibility. It requires more sophistication
2234than the approaches described in Software Project Survival Guide and Extreme Programming
2235Explained: Embrace Change.
2236McConnell, Steve. Rapid Development. Redmond, WA: Microsoft Press, 1996. This
2237book presents a toolbox approach to project planning. An experienced project planner
2238can use the tools presented in this book to create a project plan that is highly
2239adapted to a project’s unique needs.
2240Boehm, Barry and Richard Turner. Balancing Agility and Discipline: A Guide for the Perplexed.
2241Boston, MA: Addison-Wesley, 2003. This book explores the contrast between
2242agile development and plan-driven development styles. Chapter 3 has four especially
2243Key Points 59
2244revealing sections: “A Typical Day using PSP/TSP,†“A Typical Day using Extreme Programming,â€
2245“A Crisis Day using PSP/TSP,†and “A Crisis Day using Extreme Programming.â€
2246Chapter 5 is on using risk to balance agility, which provides incisive guidance
2247for selecting between agile and plan-driven methods. Chapter 6, “Conclusions,†is also
2248well balanced and gives great perspective. Appendix E is a gold mine of empirical data
2249on agile practices.
2250Larman, Craig. Agile and Iterative Development: A Manager’s Guide. Boston, MA: Addison
2251Wesley, 2004. This is a well-researched introduction to flexible, evolutionary
2252development styles. It overviews Scrum, Extreme Programming, the Unified Process,
2253and Evo.
2254cc2e.com/0386 Checklist: Upstream Prerequisites
2255①Have you identified the kind of software project you’re working on and tailored
2256your approach appropriately?
2257â‘ Are the requirements sufficiently well defined and stable enough to begin
2258construction? (See the requirements checklist for details.)
2259â‘ Is the architecture sufficiently well defined to begin construction? (See the
2260architecture checklist for details.)
2261â‘ Have other risks unique to your particular project been addressed, such
2262that construction is not exposed to more risk than necessary?
2263Key Points
2264â– The overarching goal of preparing for construction is risk reduction. Be sure
2265your preparation activities are reducing risks, not increasing them.
2266â– If you want to develop high-quality software, attention to quality must be part of
2267the software-development process from the beginning to the end. Attention to
2268quality at the beginning has a greater influence on product quality than attention
2269at the end.
2270■Part of a programmer’s job is to educate bosses and coworkers about the software-
2271development process, including the importance of adequate preparation
2272before programming begins.
2273■The kind of project you’re working on significantly affects construction prerequisites—
2274many projects should be highly iterative, and some should be more
2275sequential.
2276■If a good problem definition hasn’t been specified, you might be solving the
2277wrong problem during construction.
227860 Chapter 3: Measure Twice, Cut Once: Upstream Prerequisites
2279■If good requirements work hasn’t been done, you might have missed important
2280details of the problem. Requirements changes cost 20 to 100 times as much in
2281the stages following construction as they do earlier, so be sure the requirements
2282are right before you start programming.
2283■If a good architectural design hasn’t been done, you might be solving the right
2284problem the wrong way during construction. The cost of architectural changes
2285increases as more code is written for the wrong architecture, so be sure the architecture
2286is right, too.
2287â– Understand what approach has been taken to the construction prerequisites on
2288your project, and choose your construction approach accordingly.
228961
2290Chapter 4
2291Key Construction Decisions
2292cc2e.com/0489 Contents
2293â– 4.1 Choice of Programming Language: page 61
2294â– 4.2 Programming Conventions: page 66
2295â– 4.3 Your Location on the Technology Wave: page 66
2296â– 4.4 Selection of Major Construction Practices: page 69
2297Related Topics
2298â– Upstream prerequisites: Chapter 3
2299■Determine the kind of software you’re working on: Section 3.2
2300â– How program size affects construction: Chapter 27
2301â– Managing construction: Chapter 28
2302â– Software design: Chapter 5, and Chapters 6 through 9
2303Once you’re sure an appropriate groundwork has been laid for construction, preparation
2304turns toward more construction-specific decisions. Chapter 3, “Measure Twice,
2305Cut Once: Upstream Prerequisites,†discussed the software equivalent of blueprints
2306and construction permits. You might not have had much control over those preparations,
2307so the focus of that chapter was on assessing what you have to work with when
2308construction begins. This chapter focuses on preparations that individual programmers
2309and technical leads are responsible for, directly or indirectly. It discusses the software
2310equivalent of how to select specific tools for your tool belt and how to load your
2311truck before you head out to the job site.
2312If you feel you’ve read enough about construction preparations already, you might
2313skip ahead to Chapter 5, “Design in Construction.â€
23144.1 Choice of Programming Language
2315By relieving the brain of all unnecessary work, a good notation sets it free to concentrate
2316on more advanced problems, and in effect increases the mental power of
2317the race. Before the introduction of the Arabic notation, multiplication was difficult,
2318and the division even of integers called into play the highest mathematical
2319faculties. Probably nothing in the modern world would have more astonished a
2320Greek mathematician than to learn that ... a huge proportion of the population
232162 Chapter 4: Key Construction Decisions
2322of Western Europe could perform the operation of division for the largest numbers.
2323This fact would have seemed to him a sheer impossibility.... Our modern
2324power of easy reckoning with decimal fractions is the almost miraculous result of
2325the gradual discovery of a perfect notation.
2326—Alfred North Whitehead
2327The programming language in which the system will be implemented should be of
2328great interest to you since you will be immersed in it from the beginning of construction
2329to the end.
2330Studies have shown that the programming-language choice affects productivity and
2331code quality in several ways.
2332Programmers are more productive using a familiar language than an unfamiliar one.
2333Data from the Cocomo II estimation model shows that programmers working in a language
2334they’ve used for three years or more are about 30 percent more productive than
2335programmers with equivalent experience who are new to a language (Boehm et al.
23362000). An earlier study at IBM found that programmers who had extensive experience
2337with a programming language were more than three times as productive as those with
2338minimal experience (Walston and Felix 1977). (Cocomo II is more careful to isolate
2339effects of individual factors, which accounts for the different results of the two studies.)
2340Programmers working with high-level languages achieve better productivity and quality
2341than those working with lower-level languages. Languages such as C++, Java, Smalltalk,
2342and Visual Basic have been credited with improving productivity, reliability, simplicity,
2343and comprehensibility by factors of 5 to 15 over low-level languages such as assembly
2344and C (Brooks 1987, Jones 1998, Boehm 2000). You save time when you don’t need to
2345have an awards ceremony every time a C statement does what it’s supposed to. Moreover,
2346higher-level languages are more expressive than lower-level languages. Each line of
2347code says more. Table 4-1 shows typical ratios of source statements in several high-level
2348languages to the equivalent code in C. A higher ratio means that each line of code in the
2349language listed accomplishes more than does each line of code in C.
2350Table 4-1 Ratio of High-Level-Language Statements to Equivalent C Code
2351Language Level Relative to C
2352C 1
2353C++ 2.5
2354Fortran 95 2
2355Java 2.5
2356Perl 6
2357Python 6
2358Smalltalk 6
2359Microsoft Visual Basic 4.5
2360Source: Adapted from Estimating Software Costs (Jones 1998), Software Cost Estimation with Cocomo II
2361(Boehm 2000), and “An Empirical Comparison of Seven Programming Languages†(Prechelt 2000).
23621
23632
23643
2365HARD DATA
23664.1 Choice of Programming Language 63
2367Some languages are better at expressing programming concepts than others. You can
2368draw a parallel between natural languages such as English and programming languages
2369such as Java and C++. In the case of natural languages, the linguists Sapir and
2370Whorf hypothesize a relationship between the expressive power of a language and the
2371ability to think certain thoughts. The Sapir-Whorf hypothesis says that your ability to
2372think a thought depends on knowing words capable of expressing the thought. If you
2373don’t know the words, you can’t express the thought and you might not even be able
2374to formulate it (Whorf 1956).
2375Programmers may be similarly influenced by their languages. The words available in a
2376programming language for expressing your programming thoughts certainly determine
2377how you express your thoughts and might even determine what thoughts you
2378can express.
2379Evidence of the effect of programming languages on programmers’ thinking is common.
2380A typical story goes like this: “We were writing a new system in C++, but most of
2381our programmers didn’t have much experience in C++. They came from Fortran backgrounds.
2382They wrote code that compiled in C++, but they were really writing disguised
2383Fortran. They stretched C++ to emulate Fortran’s bad features (such as gotos
2384and global data) and ignored C++’s rich set of object-oriented capabilities.†This phenomenon
2385has been reported throughout the industry for many years (Hanson 1984,
2386Yourdon 1986a).
2387Language Descriptions
2388The development histories of some languages are interesting, as are their general capabilities.
2389Here are descriptions of the most common languages in use today.
2390Ada
2391Ada is a general-purpose, high-level programming language based on Pascal. It was
2392developed under the aegis of the Department of Defense and is especially well suited
2393to real-time and embedded systems. Ada emphasizes data abstraction and information
2394hiding and forces you to differentiate between the public and private parts of each
2395class and package. “Ada†was chosen as the name of the language in honor of Ada
2396Lovelace, a mathematician who is considered to have been the world’s first programmer.
2397Today, Ada is used primarily in military, space, and avionics systems.
2398Assembly Language
2399Assembly language, or “assembler,†is a kind of low-level language in which each statement
2400corresponds to a single machine instruction. Because the statements use specific
2401machine instructions, an assembly language is specific to a particular processor—
2402for example, specific Intel or Motorola CPUs. Assembler is regarded as the secondgeneration
2403language. Most programmers avoid it unless they’re pushing the limits in
2404execution speed or code size.
240564 Chapter 4: Key Construction Decisions
2406C
2407C is a general-purpose, mid-level language that was originally associated with the
2408UNIX operating system. C has some high-level language features, such as structured
2409data, structured control flow, machine independence, and a rich set of operators. It
2410has also been called a “portable assembly language†because it makes extensive use of
2411pointers and addresses, has some low-level constructs such as bit manipulation, and
2412is weakly typed.
2413C was developed in the 1970s at Bell Labs. It was originally designed for and used on
2414the DEC PDP-11—whose operating system, C compiler, and UNIX application programs
2415were all written in C. In 1988, an ANSI standard was issued to codify C, which
2416was revised in 1999. C was the de facto standard for microcomputer and workstation
2417programming in the 1980s and 1990s.
2418C++
2419C++, an object-oriented language founded on C, was developed at Bell Laboratories in
2420the 1980s. In addition to being compatible with C, C++ provides classes, polymorphism,
2421exception handling, templates, and it provides more robust type checking
2422than C does. It also provides an extensive and powerful standard library.
2423C#
2424C# is a general-purpose, object-oriented language and programming environment
2425developed by Microsoft with syntax similar to C, C++, and Java, and it provides extensive
2426tools that aid development on Microsoft platforms.
2427Cobol
2428Cobol is an English-like programming language that was originally developed in
24291959–1961 for use by the Department of Defense. Cobol is used primarily for business
2430applications and is still one of the most widely used languages today, second
2431only to Visual Basic in popularity (Feiman and Driver 2002). Cobol has been updated
2432over the years to include mathematical functions and object-oriented capabilities. The
2433acronym “Cobol†stands for COmmon Business-Oriented Language.
2434Fortran
2435Fortran was the first high-level computer language, introducing the ideas of variables
2436and high-level loops. “Fortran†stands for FORmula TRANslation. Fortran was originally
2437developed in the 1950s and has seen several significant revisions, including Fortran
243877 in 1977, which added block-structured if-then-else statements and characterstring
2439manipulations. Fortran 90 added user-defined data types, pointers, classes, and
2440a rich set of operations on arrays. Fortran is used mainly in scientific and engineering
2441applications.
24424.1 Choice of Programming Language 65
2443Java
2444Java is an object-oriented language with syntax similar to C and C++ that was developed
2445by Sun Microsystems, Inc. Java was designed to run on any platform by converting
2446Java source code to byte code, which is then run in each platform within an
2447environment known as a virtual machine. Java is in widespread use for programming
2448Web applications.
2449JavaScript
2450JavaScript is an interpreted scripting language that was originally loosely related to
2451Java. It is used primarily for client-side programming such as adding simple functions
2452and online applications to Web pages.
2453Perl
2454Perl is a string-handling language that is based on C and several UNIX utilities. Perl is
2455often used for system administration tasks, such as creating build scripts, as well as
2456for report generation and processing. It’s also used to create Web applications such as
2457Slashdot. The acronym “Perl†stands for Practical Extraction and Report Language.
2458PHP
2459PHP is an open-source scripting language with a simple syntax similar to Perl, Bourne
2460Shell, JavaScript, and C. PHP runs on all major operating systems to execute serverside
2461interactive functions. It can be embedded in Web pages to access and present
2462database information. The acronym “PHP†originally stood for Personal Home Page
2463but now stands for PHP: Hypertext Processor.
2464Python
2465Python is an interpreted, interactive, object-oriented language that runs in numerous
2466environments. It is used most commonly for writing scripts and small Web applications
2467and also contains some support for creating larger programs.
2468SQL
2469SQL is the de facto standard language for querying, updating, and managing relational
2470databases. “SQL†stands for Structured Query Language. Unlike other languages
2471listed in this section, SQL is a “declarative language,†meaning that it does not
2472define a sequence of operations, but rather the result of some operations.
2473Visual Basic
2474The original version of Basic was a high-level language developed at Dartmouth College
2475in the 1960s. The acronym BASIC stands for Beginner’s All-purpose Symbolic
247666 Chapter 4: Key Construction Decisions
2477Instruction Code. Visual Basic is a high-level, object-oriented, visual programming
2478version of Basic developed by Microsoft that was originally designed for creating
2479Microsoft Windows applications. It has since been extended to support customization
2480of desktop applications such as Microsoft Office, creation of Web programs,
2481and other applications. Experts report that by the early 2000s more professional
2482developers were working in Visual Basic than in any other language (Feiman and
2483Driver 2002).
24844.2 Programming Conventions
2485Cross-Reference For more
2486details on the power of conventions,
2487see Sections 11.3
2488through 11.5.
2489In high-quality software, you can see a relationship between the conceptual integrity
2490of the architecture and its low-level implementation. The implementation must be
2491consistent with the architecture that guides it and consistent internally. That’s the
2492point of construction guidelines for variable names, class names, routine names, formatting
2493conventions, and commenting conventions.
2494In a complex program, architectural guidelines give the program structural balance
2495and construction guidelines provide low-level harmony, articulating each class as a
2496faithful part of a comprehensive design. Any large program requires a controlling
2497structure that unifies its programming-language details. Part of the beauty of a large
2498structure is the way in which its detailed parts bear out the implications of its architecture.
2499Without a unifying discipline, your creation will be a jumble of sloppy variations
2500in style. Such variations tax your brain—and only for the sake of understanding coding-
2501style differences that are essentially arbitrary. One key to successful programming
2502is avoiding arbitrary variations so that your brain can be free to focus on the variations
2503that are really needed. For more on this, see “Software’s Primary Technical Imperative:
2504Managing Complexity†in Section 5.2.
2505What if you had a great design for a painting, but one part was classical, one impressionist,
2506and one cubist? It wouldn’t have conceptual integrity no matter how closely
2507you followed its grand design. It would look like a collage. A program needs low-level
2508integrity, too.
2509Before construction begins, spell out the programming conventions you’ll use. Coding-
2510convention details are at such a level of precision that they’re nearly impossible to
2511retrofit into software after it’s written. Details of such conventions are provided
2512throughout the book.
25134.3 Your Location on the Technology Wave
2514During my career I’ve seen the PC’s star rise while the mainframe’s star dipped toward
2515the horizon. I’ve seen GUI programs replace character-based programs. And I’ve seen
2516the Web ascend while Windows declines. I can only assume that by the time you read
2517KEY POINT
25184.3 Your Location on the Technology Wave 67
2519this some new technology will be in ascendance, and Web programming as I know it
2520today (2004) will be on its way out. These technology cycles, or waves, imply different
2521programming practices depending on where you find yourself on the wave.
2522In mature technology environments—the end of the wave, such as Web programming
2523in the mid-2000s—we benefit from a rich software development infrastructure. Latewave
2524environments provide numerous programming language choices, comprehensive
2525error checking for code written in those languages, powerful debugging tools,
2526and automatic, reliable performance optimization. The compilers are nearly bug-free.
2527The tools are well documented in vendor literature, in third-party books and articles,
2528and in extensive Web resources. Tools are integrated, so you can do UI, database,
2529reports, and business logic from within a single environment. If you do run into problems,
2530you can readily find quirks of the tools described in FAQs. Many consultants
2531and training classes are also available.
2532In early-wave environments—Web programming in the mid-1990s, for example—the
2533situation is the opposite. Few programming language choices are available, and those
2534languages tend to be buggy and poorly documented. Programmers spend significant
2535amounts of time simply trying to figure out how the language works instead of writing
2536new code. Programmers also spend countless hours working around bugs in the language
2537products, underlying operating system, and other tools. Programming tools in
2538early-wave environments tend to be primitive. Debuggers might not exist at all, and
2539compiler optimizers are still only a gleam in some programmer’s eye. Vendors revise
2540their compiler version often, and it seems that each new version breaks significant
2541parts of your code. Tools aren’t integrated, and so you tend to work with different
2542tools for UI, database, reports, and business logic. The tools tend not to be very compatible,
2543and you can expend a significant amount of effort just to keep existing functionality
2544working against the onslaught of compiler and library releases. If you run
2545into trouble, reference literature exists on the Web in some form, but it isn’t always
2546reliable and, if the available literature is any guide, every time you encounter a problem
2547it seems as though you’re the first one to do so.
2548These comments might seem like a recommendation to avoid early-wave programming,
2549but that isn’t their intent. Some of the most innovative applications arise from
2550early-wave programs, like Turbo Pascal, Lotus 123, Microsoft Word, and the Mosaic
2551browser. The point is that how you spend your programming days will depend on
2552where you are on the technology wave. If you’re in the late part of the wave, you can
2553plan to spend most of your day steadily writing new functionality. If you’re in the early
2554part of the wave, you can assume that you’ll spend a sizeable portion of your time trying
2555to figure out your programming language’s undocumented features, debugging
2556errors that turn out to be defects in the library code, revising code so that it will work
2557with a new release of some vendor’s library, and so on.
2558When you find yourself working in a primitive environment, realize that the programming
2559practices described in this book can help you even more than they can in mature
256068 Chapter 4: Key Construction Decisions
2561environments. As David Gries pointed out, your programming tools don’t have to
2562determine how you think about programming (1981). Gries makes a distinction
2563between programming in a language vs. programming into a language. Programmers
2564who program “in†a language limit their thoughts to constructs that the language
2565directly supports. If the language tools are primitive, the programmer’s thoughts will
2566also be primitive.
2567Programmers who program “into†a language first decide what thoughts they want to
2568express, and then they determine how to express those thoughts using the tools provided
2569by their specific language.
2570Example of Programming into a Language
2571In the early days of Visual Basic, I was frustrated because I wanted to keep the business
2572logic, the UI, and the database separate in the product I was developing, but
2573there wasn’t any built-in way to do that in the language. I knew that if I wasn’t careful,
2574over time some of my Visual Basic “forms†would end up containing business logic,
2575some forms would contain database code, and some would contain neither—I would
2576end up never being able to remember which code was located in which place. I had
2577just completed a C++ project that had done a poor job of separating those issues, and
2578I didn’t want to experience déjà vu of those headaches in a different language.
2579Consequently, I adopted a design convention that the .frm file (the form file) was
2580allowed only to retrieve data from the database and store data back into the database.
2581It wasn’t allowed to communicate that data directly to other parts of the program.
2582Each form supported an IsFormCompleted() routine, which was used by the calling
2583routine to determine whether the form that had been activated had saved its data.
2584IsFormCompleted() was the only public routine that forms were allowed to have.
2585Forms also weren’t allowed to contain any business logic. All other code had to be
2586contained in an associated .bas file, including validity checks for entries in the form.
2587Visual Basic did not encourage this kind of approach. It encouraged programmers to
2588put as much code into the .frm file as possible, and it didn’t make it easy for the .frm
2589file to call back into an associated .bas file.
2590This convention was pretty simple, but as I got deeper into my project, I found that it
2591helped me avoid numerous cases in which I would have been writing convoluted code
2592without the convention. I would have been loading forms but keeping them hidden so
2593that I could call the data-validity-checking routines inside them, or I would have been
2594copying code from the forms into other locations and then maintaining parallel code
2595in multiple places. The IsFormCompleted() convention also kept things simple.
2596Because every form worked exactly the same way, I never had to second-guess the
2597semantics of IsFormCompleted()—it meant the same thing every time it was used.
25984.4 Selection of Major Construction Practices 69
2599Visual Basic didn’t support this convention directly, but my use of a simple programming
2600convention—programming into the language—made up for the language’s lack of
2601structure at that time and helped keep the project intellectually manageable.
2602Understanding the distinction between programming in a language and programming
2603into one is critical to understanding this book. Most of the important programming
2604principles depend not on specific languages but on the way you use them. If
2605your language lacks constructs that you want to use or is prone to other kinds of problems,
2606try to compensate for them. Invent your own coding conventions, standards,
2607class libraries, and other augmentations.
26084.4 Selection of Major Construction Practices
2609Part of preparing for construction is deciding which of the many available good practices
2610you’ll emphasize. Some projects use pair programming and test-first development,
2611while others use solo development and formal inspections. Either combination
2612of techniques can work well, depending on specific circumstances of the project.
2613The following checklist summarizes the specific practices you should consciously
2614decide to include or exclude during construction. Details of these practices are contained
2615throughout the book.
2616cc2e.com/0496 Checklist: Major Construction Practices
2617Coding
2618â‘ Have you defined how much design will be done up front and how much
2619will be done at the keyboard, while the code is being written?
2620â‘ Have you defined coding conventions for names, comments, and layout?
2621â‘ Have you defined specific coding practices that are implied by the architecture,
2622such as how error conditions will be handled, how security will be
2623addressed, what conventions will be used for class interfaces, what standards
2624will apply to reused code, how much to consider performance while
2625coding, and so on?
2626â‘ Have you identified your location on the technology wave and adjusted
2627your approach to match? If necessary, have you identified how you will
2628program into the language rather than being limited by programming in it?
2629Teamwork
2630①Have you defined an integration procedure—that is, have you defined the
2631specific steps a programmer must go through before checking code into
2632the master sources?
2633â‘ Will programmers program in pairs, or individually, or some combination
2634of the two?
2635KEY POINT
263670 Chapter 4: Key Construction Decisions
2637Cross-Reference For more
2638details on quality assurance,
2639see Chapter 20, “The Software-
2640Quality Landscape.â€
2641Quality Assurance
2642â‘ Will programmers write test cases for their code before writing the code
2643itself?
2644â‘ Will programmers write unit tests for their code regardless of whether
2645they write them first or last?
2646â‘ Will programmers step through their code in the debugger before they
2647check it in?
2648â‘ Will programmers integration-test their code before they check it in?
2649①Will programmers review or inspect each other’s code?
2650Cross-Reference For more
2651details on tools, see Chapter
265230, “Programming Tools.â€
2653Tools
2654â‘ Have you selected a revision control tool?
2655â‘ Have you selected a language and language version or compiler version?
2656â‘ Have you selected a framework such as J2EE or Microsoft .NET or explicitly
2657decided not to use a framework?
2658â‘ Have you decided whether to allow use of nonstandard language features?
2659①Have you identified and acquired other tools you’ll be using—editor, refactoring
2660tool, debugger, test framework, syntax checker, and so on?
2661Key Points
2662â– Every programming language has strengths and weaknesses. Be aware of the
2663specific strengths and weaknesses of the language you’re using.
2664■Establish programming conventions before you begin programming. It’s nearly
2665impossible to change code to match them later.
2666â– More construction practices exist than you can use on any single project. Consciously
2667choose the practices that are best suited to your project.
2668■Ask yourself whether the programming practices you’re using are a response to
2669the programming language you’re using or controlled by it. Remember to program
2670into the language, rather than programming in it.
2671■Your position on the technology wave determines what approaches will be effective—
2672or even possible. Identify where you are on the technology wave, and
2673adjust your plans and expectations accordingly.