Showing posts with label design. Show all posts
Showing posts with label design. Show all posts

Monday, April 09, 2018

How can I become a software developer who only designs?

A young programmer asked me, "How can I become a software developer who only designs the whole software architecture and gives instructions to other developers rather than actually coding by myself?"

I told him he could do that right away, as long as he didn’t care if the other developers listened to his instructions and followed them. And if he didn't care of he was paid.

In general, software developers will not follow the lead of someone for whose designs they have no respect. And why would they respect your designs unless you had previously proved yourself by what you’ve built?

So, build things, and build more things, until you demonstrate that others have some reason to follow your lead.


And, at the same time, work on your people skills, because even if you’re the greatest designer in the world, if you’re a self-centered jerk, nobody will follow you or your designs.

For more on designing, see

Saturday, January 06, 2018

New: #System #Design #Heuristics

You'd think that after publishing books for half a century, I'd know how to write a book. If that's what you think, you'd be wrong.

Sure, I've even written a book on writing books (Weinberg on Writing, the Fieldstone Method), and I've applied those methods to dozens of successful books. But way back around 1960, I started collecting notes on the process of design, thinking I would shortly gather them into a book. Back then, I didn't call these bits and pieces "fieldstones," but that's what they turned out to be: the pieces that, when assembled properly, would ultimately become my design book.

Ultimately? Assembled properly? Aye, there's the rub!

Building walls from randomly found fieldstones requires patience. So does writing books by the Fieldstone Method. My Introduction to General Systems Thinking took fourteen years to write. But a writer only lives one lifetime, so there's a limit to patience. I'm growing old, and I'm beginning to think that fifty years is as close to "ultimately" as I'm going to get.

So, I've begun to tackle the task of properly assembling my collection of design fieldstones. Unfortunately, it's a much larger collection that I'd ever tackled before. My Mac tells me I have more than 36,000,000 digitized bytes of notes. My filing cabinets told me I had more than twenty-five pounds of paper notes, but I've managed to digitize some of them and discard others, so there's only a bit more than ten pounds left to consider.

For the past couple of years, I've periodically perused these fieldstones and tried to assemble them "properly." I just can't seem to do it. I'm stuck.

Some writers would say I am suffering from "writer's block," but I believe "writer's block" is a myth. I've published three other books in these frustrating years, so I can't be "blocked" as a writer, but just over this specific design book. You can hear me talk more about the Writer's Block myth on YouTube 

[https://www.youtube.com/watch?v=77xrdj9YH3M&t=7s]

but the short version is that "blocking" is simply a lack of ideas about how to write. I finally decided to take my own advice and conjure up some new ideas about how to write this design book.

Why I Was Stuck

To properly assemble a fieldstone pile, I always need an "organizing principle." For instance, my recent book, Do You Want to Be a (Better) Manager? is organized around the principle of better management. Or, for my book, Errors, the principle is actually the title.  So, I had been thinking the organizing principle for a book on design ought to be Design

Well, that seemed simple enough, but there was a problem. Everybody seemed to know what design is, but nobody seemed able to give a clear, consistent definition that covered all my notes. I finally came to the conclusion that's because "design" is not one thing, but many, many different things.

In the past, I ran a forum (SHAPE: Software as a Human Activity Practiced Effectively) whose members were among the most skilled software professionals in the world. We held a number of threads on the subject, "What is Design?" The result was several hundred pages of brilliant thoughts about design, all of which were correct in some context. But many of them were contradictory.

Some said design was a bottom-up process, but others asserted it was top-down. Still others talked about some kind of sideways process, and there were several of these. Some argued for an intuitive process, but others laid out an algorithmic, step-by-step process. There were many other variations: designs as imagined (intentional designs), designs as implemented, and designs as evolved in the world. All in all, there were simply too many organizing principles—certainly too many to compress into a title, let alone organize an entire book.

After two years of fumbling, I finally came up with an idea that couldn't have been implemented fifty years ago: the book will be composed of a variety of those consulting ideas that have been most helpful to my clients' designers. I will make no attempt (or very little) to organize them, but release them incrementally in an ever-growing ebook titled Design Heuristics.

How to Buy System Design Heuristics

My plan for offering the book is actually an old one, using a new technology. More than a century ago Charles Dickens released many of his immortal novels one chapter at a time in the weekly newspaper. Today, using the internet, I will release System Design Heuristics a single element at a time to subscribing readers.

To subscribe to the book, including all future additions, a reader will make a one-time payment. The price will be quite low when the collection is small, but will grow as the collection grows. That way, early subscribers will receive a bargain in compensation for the risk of an unknown future. Hopefully, however, even the small first collection will be worth the price. (If not, there will be a full money-back guarantee.)

Good designs tend to have unexpected benefits. When I first thought of this design, I didn't realize that it would allow readers to contribute ideas that I might incorporate in each new release. Now I aware of that potential benefit, and look forward to it.

Before I upload the first increment of System Design Heuristics, I'll wait a short while for feedback on this idea from my readers. If you'd like to tell me something about the plan, email me or write a comment on this blog.

Thanks for listening. Tell me what you think.

Monday, December 25, 2017

Unnecessary Code

We were asked, "How can I tell if my code does extra unnecessary work?"
To answer this question well, I’d need to know what you mean by “unnecessary.” Not knowing your meaning, I’ll just mention one kind of code I would consider unnecessary: code that makes your program run slower than necessary but can be replaced with faster code.

To rid your program of such unnecessary code, start by timing the program’s operations. If it’s fast enough, then you’re done. You have no unnecessary code of this type.

If it’s not fast enough, then you’ll want to run a profiler that shows where the time is being spent. Then you search those areas (there can be only one that consumes more than half the time) and work it over, looking first at the design.

There’s one situation I’ve encountered where this approach can bring you trouble. Code that’s fast enough with some sets of data may be unreasonably slow with other sets. The most frequent case of this kind is when the algorithm’s time grows non-linearly with the size of the data. To prevent this kind of unnecessary code, you must do your performance testing with (possibly artificially) large data sets.

Paradoxically, though, some algorithms are faster with large data sets than small ones.

Here’s a striking example: My wife, Dani, wanted to generate tests in her large Anthropology class. She wanted to give all students the same test, but she wanted the questions for each student to be given in a random order, to prevent cheating by peeking. She gave 20 questions to a programmer who said he already had a program that would do that job. The program, however, seemed to fall into an unending loop. Closer examination eventually showed that it wasn't an infinite loop, but would have finally ended about the same time the Sun ran out of hydrogen to burn.

Here’s what happened: The program was originally built to select random test questions from a large (500+ questions) data base. The algorithm would construct a test candidate by choosing, say, twenty questions at random, then checking the twenty to see if there were any duplicates among those chosen. If there were duplicates, the program would discard that test candidate and construct another.

With a 500 question data base, there was very little chance that twenty questions chosen at random would contain a duplicate. It could happen, but throwing out a few test candidates didn’t materially affect performance. But, when the data base had only twenty questions, and all Dani wanted was to randomize the order of the questions, the situation was quite different.

Choosing twenty from twenty at random (with replacement) was VERY likely to produce duplicates, so virtually every candidate was discarded, but the program just ground away, trying to find that rare set of twenty without duplicates.

As an exercise, you might want to figure out the probability of a non-duplicate set of twenty. Indeed, that’s an outstanding way to eliminate unnecessary code: by analyzing your algorithm before coding it.

Over the years, I’ve seen many other things you might consider unnecessary, but which do no harm except to the reputation of the programmer. For example:
* Setting a value that’s already set.
* Sorting a table that’s already sorted.
* Testing a variable that can have only one value.

These redundancies are found by reading the program, and may be important for another reason besides performance. Such idiotic pieces of code may be indications that the code was written carelessly, or perhaps modified by someone without full understanding. In such cases, there’s quite likely to be an error nearby, so don’t just ignore them.


Wednesday, December 20, 2017

Which code is more readable?

We were asked, "Which code is more readable, one that uses longer variable names or short ones?" 

Maybe some historical perspective will help answer this question.

In the very early days of computing (I was there), we used short variable names because:

* Programs were fairly short and simple, so scope wasn’t much of a problem.

  • Memories were small, so programmers didn’t want to waste memory with long names.

  • Compilers and assemblers were slow, and long names made them slower.

  • Many compilers and assemblers wouldn’t allow names longer than a few characters, because of speed and memory limitations.

  • We didn’t think much, if at all, about who would maintain a program once it left the hands of the original programmer.

As programs grew larger, one result of short naming was difficult maintenance, so the movement toward longer names grew stronger. It wasn’t helped by COBOL, which asserted that executives should be able to read code. Lots of COBOL code was littered with super-long names, but that didn't help executives read it.

The COBOL argument proved to be nonsense. Still, the maintenance argument for longer, more descriptive names made sense.

Unfortunately, like many movements, the long-name movement went too far, at least for my taste. It wasn’t because long names were harder to write. After all, a typical program is written oncem but read for modification and testing many, many times. So, if long names really made reading easier and more reliable, it was good.

But the length of a name is not really the issue. I’ve seen many programs with long, long names that were so similar that they were easily confused, one with another. For instance, we once wasted many days trying to find an error when the name radar_data_station_#46395_azimuth_reading was mistaken for radar_data_station_#46895_azimuth_reading. Psychologists and writers know well that items in the middle of long lists are frequently glossed over.

So, like lots of other things in software development, long versus short names becomes a tradeoff, a design decision for a programmer for which there is no “right” answer. Programmers must design their name-sets with the same kind of engineering thought they put into all their design decisions.

And, as maintainers modify a program, they must maintain the name-set, so as to avoid building up design debt as the program ages.

So, sorry, there’s no easy answer to this question, nothing a programmer can apply  mindlessly. Just as it’s always been, programmers who think will do a better job than those who blindly follow simplistic rules.



Monday, February 13, 2017

Should I learn C++ or Python?

When I first saw this question on Quora, there were already 47 answers, pretty much all of them wrong. But the number of different answers tells you something: choice of programming language is more of a religious question than a technical one. The fact is that if you want to be a professional programmer, you should learn both—and at the same time.

When we teach programming, we always teach at least two languages at the same time, in parallel. Assignments must be done in both (or more) languages, submitted along with a short essay on why the solutions are different, and why the same. That’s the way to develop some wisdom and maturity in the coding part of your professional work.

Some of the respondents asserted that programming languages are tools. If that’s an appropriate metaphor, then how would you answer this question of a wannabe carpenter:

"Should I learn saws or screwdrivers?"

Do you think someone could be a top-flight carpenter knowing only one?

So, stay out of this quasi-religious controversy, which can never be settled. Instead, spend your valuable time learning as many different programming languages as possible, at least 5 or 6. You won’t necessarily use all of them, but knowing their different approaches will put you far above those dullards who say:

“I only know Language X, but it I still think it’s the best language in the world.”




Sunday, August 07, 2016

What Is Quality? Why Is It Important?


(This post is taken from the beginning of Chapter 1 of Book 1 of my Quality Sofware Series: How Software is Built.)



"You can fool all of the people some of the time, and some of the people all of the time, but you can't fool all of the people all of the time."- Abraham Lincoln
People in the software business put great stress on removing ambiguity, and so do writers. But sometimes writers are intentionally ambiguous, as in the title of this book. "Quality Software Management" means both "the management of quality software" and "quality management in the software business," because I believe that the two are inseparable. Both meanings turn on the word "quality," so if we are to keep the ambiguity within reasonable bounds, we first need to address the meaning of that often misunderstood term.
1.1 A Tale Of Software Quality
My sister's daughter, Terra, is the only one in the family who has followed Uncle Jerry in the writer's trade. She writes fascinating books on the history of medicine, and I follow each one's progress as if it were one of my own. For that reason, I was terribly distressed when her first book, Disease in the Popular American Press, came out with a number of gross typographical errors in which whole segments of text disappeared (see Figure 1-1). I was even more distressed to discover that those errors were caused by an error in the word processing software she used—CozyWrite, published by one of my clients, the MiniCozy Software Company.
                                                                                                   
The next day, too, the Times printed a letter from "Medicus," objecting to the misleading implication in the microbe story that diphtheria could ever be inoculated against; the writer flatly asserted that there would never be a vaccine for this disease because, unlike smallpox, diphtheria re-

Because Times articles never included proof—never told how people knew what they claimed—the uninformed reader had no way to distinguish one claim from another.
                                                                                                   
Figure 1-1. Part of a sample page from Terra Ziporyn's book showing how the CozyWrite word processor lost text after "re-" in Terra's book.

Terra asked me to discuss the matter with MiniCozy on my next visit. I located the project manager for CozyWrite, and he acknowledged the existence of the error.
"It's a rare bug," he said.
"I wouldn't say so," I countered. "I found over twenty-five instances in her book."
"But it would only happen in a book-sized project. Out of over 100,000 customers, we probably didn't have 10 who undertook a project of that size as a single file."
"But my niece noticed. It was her first book, and she was devastated."
"Naturally I'm sorry for her, but it wouldn't have made any sense for us to try to fix the bug for 10 customers."
"Why not? You advertise that CozyWrite handles book-sized projects."
"We tried to do that, but the features didn't work. Eventually, we'll probably fix them, but for now, chances are we would introduce a worse bug—one that would affect hundreds or thousands of customers. I believe we did the right thing."
As I listened to this project manager, I found myself caught in an emotional trap. As software consultant to MiniCozy, I had to agree, but as uncle to an author, I was violently opposed to his line of reasoning. If someone at that moment had asked me, "Is CozyWrite a quality product?" I would have been tongue-tied.
How would you have answered?
1.2 The Relativity of Quality
The reason for my dilemma lies in the relativity of quality. As the MiniCozy story crisply illustrates, what is adequate quality to one person may be inadequate quality to another.
1.2.1. Finding the relativity
If you examine various definitions of quality, you will always find this relativity. You may have to examine with care, though, for the relativity is often hidden, or at best, implicit.
Take for example Crosby's definition:
"Quality is meeting requirements."
Unless your requirements come directly from heaven (as some developers seem to think), a more precise statement would be:
"Quality is meeting some person's requirements."
For each different person, the same product will generally have different "quality," as in the case of my niece's word processor. My MiniCozy dilemma is resolved once I recognize that
a. To Terra, the people involved were her readers.
b. To MiniCozy's project manager, the people involved were (the majority of) his customers.
1.2.2 Who was that masked man?
In short, quality does not exist in a non-human vacuum.
Every statement about quality is a statement about some person(s).
That statement may be explicit or implicit. Most often, the "who" is implicit, and statements about quality sound like something Moses brought down from Mount Sinai on a stone tablet. That's why so many discussions of software quality are unproductive: It's my stone tablet versus your Golden Calf.
When we encompass the relativity of quality, we have a tool to make those discussions more fruitful. Each time somebody asserts a definition of software quality, we simply ask,
"Who is the person behind that statement about quality."
Using this heuristic, let's consider a few familiar but often conflicting ideas about what constitutes software quality:
a. "Zero defects is high quality."
1. to a user such as a surgeon whose work would be disturbed by those defects
2. to a manager who would be criticized for those defects
b. "Lots of features is high quality."
1. to users whose work can use those features—if they know about them
2. to marketers who believe that features sell products
c. "Elegant coding is high quality."
1. to developers who place a high value on the opinions of their peers
2. to professors of computer science who enjoy elegance
d. "High performance is high quality."
1. to users whose work taxes the capacity of their machines
2. to salespeople who have to submit their products to benchmarks
e. "Low development cost is high quality."
1. to customers who wish to buy thousands of copies of the software
2. to project managers who are on tight budgets
f. "Rapid development is high quality."
1. to users whose work is waiting for the software
2. to marketers who want to colonize a market before the competitors can get in
g. "User-friendliness is high quality."
1. to users who spend 8 hours a day sitting in front of a screen using the software

2. to users who can't remember interface details from one use to the next

Sunday, May 22, 2016

How can I be a faster programmer?

Recently, "Tommy" posted the following question on Quora, a question-answer site with lots of good stuff (and some really cheesy stuff) on a variety of topics:

How can be a faster programmer?

Tommy received a goodly portion of excellent answers, with lots of details of tips and techniques—great stuff. Reading them over, I saw that a few of the answers offered some good high-level advice, too, but that advice might be lost in all the details, so I decided to offer a summary high-level view of what I've learned about speedy programming in my 60+ years in the computer business.

First of all, read all the great answers here on Quora and incorporate these ideas, one at a time, into you programming practices. In other words, to become faster or better in some other way, KEEP LEARNING. That’s the number one way to become faster, if you want to be fast.

Second, ask yourself, with each job, “Why is programming speed so important for this job?” Often, it’s an unskilled manager who knows only a dangerous amount about programming, but can always say “work faster.” So ask yourself, what’s an appropriate speed for this job, given that speed and error are tightly related.

Third, ask yourself, “Do I really need a program for this problem?” If you don’t have to write a program at all, that gives you infinite speed. Sometimes you don’t have to write a program because one already exists that will do an adequate job. Sometimes you don’t have to write a program because a back-of-the-envelope estimate will give all the answers needed. Sometimes you don’t have to write a program because there’s no real need for the function you’ve been asked to implement.

Fourth, don’t skimp on up front work because you’re rushing to produce code. If you’re working with the wrong requirements, any nifty code you write will be worthless, so any time you spend on it will be wasted. If your design is poor, you’ll write lots of wasted code, which means more wasted time.

Fifth, when you finally have a good design for the right requirements, slow down your coding in order to go faster. We say, “Code in haste; debug at leisure.” Take whatever time you need to think clearly, to review with your colleagues, to find solid code you can reuse, to test as you build incrementally so you don’t have to backtrack.

Sixth, develop in a team, and develop your team. If you think teammates slow you down, then it’s because you haven’t put the effort into building your team. So, in fact, we’re back to the first point, but now at the team level. Keep learning as a team. Your first job is not to build code, but to build the team that builds code.

Many of these principles are developed in much more detail in my many books on software development, so if you want to learn more, take a look at my Leanpub.com author page and make some choices among about fifty books and a bundle of bundles of books. Good reading!

Tuesday, May 05, 2015

Requirements Hints and Variations

In both volumes of Exploring Requirements, we follow each chapter with a section of hints and variations about the topic of the chapter. Many readers tell us that this extra material is often more valuable than the chapter body itself. For that reason, I've decided to present a blog entry consisting entirely of  the hints and variations from the first chapter of Volume One. Enjoy!


(1) Another source of complexity in development projects is the desire of non-experts to be involved in the design of complex products. Most customers naturally prefer to learn as little as possible about product design, yet still have all their wishes met in the requirements process. When customers prefer to remain naive about the product design process, most of the burden falls on the notation—a lot to ask of a notation. The design complexity problem can be solved by creating a tutorial to convert a naive customers into an expert—but not if the customers doesn’t want to invest that kind of effort.

(2) Customers often turn away from the design process because the professional designers treat them in a patronizing manner. Remember, most participants are naive only about the development process, and are themselves experts in subjects about which the designers are naive. Such expertise is why their participation is essential. We’re much more likely to have their full participation if we create an environment of shared expertise.

(3) Methodology experts underestimate the difficulty of understanding their nota- tions, which they believe to be “intuitive.” To understand how difficult it really is to define an “intuitive” notation, consider the problem of designing universally understood international road signs.

(4) When two sets of experts participate in the same requirements process, there’s often a conflict about which notation is intuitive. Children reared in Paris think French is intuitive, but children reared in Montreal may think both French and English are intuitive. In the same way, experts often share a “first love” syndrome for notations. This first-learned-first-loved bias can be prevented in the same way bilingual children avoid a bias for one language. If you are teaching a notation, instruct your students in two at the same time. Do all maps in both notations, and compare the pair of maps explicitly.

(5) Mastery of the notation may give one party dominance in the requirements process, while excluding those who haven’t mastered the notation. To avoid political wars, you must devote attention to depoliticizing the language issue. Try following the Swiss example: All “first love” notations of participants are declared to be “official” languages of the requirements process. Every official document must be presented in all of the official languages before the process is considered complete.

(6) Although this multilingual approach may seem burdensome, the Swiss example shows it can work if done in the right spirit. Indeed, in Swiss meetings, people from the “dominant” language group often present their ideas in the “secondary” languages, as a courtesy to the minority participants and as a strong indication of how much they value their participation. In our experience with requirements work, this multilingual approach always yields a more accurate definition of requirements as well as a more complete involvement of all participants.


(7) Our colleague Eric Minch suggests a theoretical model: all descriptions of the de- signed system—including the various constituencies’ requirements and satisfactions, the constraints and decisions, and the final specifications for implementation—can be considered statements in different “languages.” In other words, instead of seeing all of these as different descriptions in a single language, we can think of them as the same description in different languages. The full design task then involves finding a way of translating among these languages, and the final product is such a translation strategy.

(8) Minch’s idea stimulated us to recall “translation” is not quite the simple one-to-one task we often assume. Some translations are works of art in themselves, like Edward FitzGerald’s English translation of The Rubaiyat of Omar Khayyam. Consider the famous quatrain:

A Book of Verses underneath the Bough, 
A Jug of Wine, a Loaf of Bread—and
Thou Beside me Singing in the Wilderness—
Oh, Wilderness were Paradise enow!

What part is original with Omar the Tentmaker, astronomer and mathematician from eleventh century Persia? What part has been added (or subtracted) by FitzGerald, the nineteenth century Suffolk gentleman? What part has been added by twenty-first century readers, such as us?

(9) Experiencing the final product, we don’t so much care if it’s an exact translation, but only whether we like the product. This verse reminds us: value can be added at any stage of the product development cycle. Requirements are merely a guide. They are to be taken literally, but not too literally. There are many roads to Paradise.

(10) These observations connect directly with a remark by Ken de Lavigne, our colleague at IBM: “Your discussion of maps brings out the great problem introduced by ‘stepwise refinement’ approaches: although they claim to postpone decisions until the time comes to make them, in fact the most far-reaching decisions are made first, when one has the least amount of information.” Always be prepared to go back and revise the “translation,” or “map,” when further exploration shows there was a wrong branch higher in the decision tree. To do this, let go of the idea of the “one right way,” or “the perfect translation.”

Extra Hint
To see an annotated catalog of all of Jerry's ebooks and bargain bundles, visit https://leanpub.com/u/jerryweinberg

To see a list of most of his books, ebooks and bound books, visit http://www.amazon.com/-/e/B000AP8TZ8

Sunday, April 26, 2015

Ending the Requirements Process

This essay is the entire chapter 5 of the second volume of Exploring Requirements.
The book can be purchased as a single volume, or volumes 1 and 2 as a bundle, or as part of the People Skills bundle. It's also available from various vendors with both volumes as one bound book.



The Book of Life begins with a man and woman in a garden. It ends with Revelations.—Oscar Wilde, A Woman of No Importance
25.1 The Fear of Ending
The requirements process begins with ambiguity. It ends not with revelations, but with agreement. More important, it ends.
But how does it end? At times, the requirements process seems like Oscar Wilde when he remarked, "I was working on the proof of one of my poems all the morning and took out a comma. In the afternoon, I put it back again."
A certain percentage, far too large, of development efforts never emerge from the requirements phase. After two, or five, or even ten years, you can dip into the ongoing requirements process and watch them take out a comma in the morning and put it back again in the afternoon. Far better the comma should be killed during requirements than allowed to live such a lingering death.
Paradoxically, it is the attempt to finish the requirements work that creates this endless living death. The requirements phase ends with agreement, but the requirements work never ends until the product is finished. There simply comes a moment when you decide you have enough agreement to risk moving on into the full design phase.
25.2 The Courage to End It All
Nobody can tell you just when to step off the cliff. It's simply a matter of courage. Whenever an act requires courage, you can be sure that people will invent ways of reducing the courage needed. The requirements process is no different, and several inventions are available to diminish the courage needed to end it all.
25.2.1 Automatic design and development
One of the persistent "inventions" to substitute for courage is some form of automatic design and/or development.
In automatic development, the finished requirements are the input to an automatic process, the output of which is the finished product. There are, today, a few simple products that can be produced in approximately this way. For instance, certain optical lenses can be manufactured automatically starting from a statement of requirements.
In terms of the decision tree, automatic development is like a tree with a trunk, one limb, no branches or twigs, and a single leaf (Figure 25-1). With such a system, finishing requirements is not a problem. When you think you might be finished, you press the button and take a look at the product that emerges. If it's not right, then you weren't finished with the requirements process.
pastedGraphic.png
Figure 25-1. Automatic development is like a tree with a trunk, one limb, no branches or twigs, and a single leaf.
No wonder this appealing dream keeps recurring. It's exactly like the age-old story of the genie in the bottle, with no limit on the number of wishes. For those few products where such a process is in place, the only advantage of a careful requirements process is to save the time and money of wasted trial products. If trial products are cheap, then we can be quite casual about finishing requirements work.
25.2.2 Hacking
Automatic development is, in effect, nothing but requirements work—all trunk and limb. At the other end of the spectrum is hacking, development work with no explicit requirements work. When we hack, we build something, try it out, modify it, and try it again. When we like what we have, we stop. In terms of the decision tree model, hacking is not a tree at all, but a bush: all branches, twigs, and leaves, with no trunk or major limb (Figure 25-2).
pastedGraphic_1.png
Figure 25-2. Hacking is not a tree at all, but a bush—all branches, twigs, and leaves, with no trunk or major limb.
Pure hacking eliminates the problem of ending requirements work, because there is no requirements work. On the other hand, we could conceive of hacking as pure requirements work—each hack is a way of finding out what we really want.
Almost any real project, no matter how well planned and managed, contains a certain amount of hacking, because the real world always plays tricks on our assumptions. People who abhor the idea of hacking may try to create a perfect requirements process. They are the very people who create "living death" requirements processes.
25.2.3 Freezing requirements
Paradoxically, hacking and automatic development are exactly the same process from the point of view of requirements. They are the same because they do not distinguish requirements work from development. Most real-world product development falls somewhere between pure hacking and automatic development, which is why we have to wrestle with the problem of ending.
Even when we have every requirement written down in the form of an agreement, we cannot consider the requirements process to be ended. We know those agreements will have to change because in the real world, assumptions will change. Some people have tried to combat their fear of changing assumptions by imposing a freeze on requirements. They move into the design phase with the brave declaration,
No changes to requirements will be allowed.
Those of us who understand the nature of the real world will readily understand why a freeze simply cannot work. We know of only one product development when it was even possible to enforce the freeze. In that instance, a software services company took a contract to develop an inventory application for a manufacturer. The requirements were frozen by being made part of the contract, and eighteen months later, the application was delivered. Although it met all the contracted requirements, the application was rejected.
This frozen product was totally unusable because in eighteen months it had become totally removed from what was really required in the here-and-now. The customer refused to pay, and the software services company threatened legal action. The customer pointed out how embarrassing it would be to a professional software company to have its "freeze fantasy" exposed in a public courtroom.
Eventually, the two parties sat down to negotiate, and the customer paid about one-fourth of the software firm's expenses. At the end of this bellicose negotiation, someone pointed out how with far less time negotiating, they could have renegotiated the requirements as they went along, and both parties would have been happy.
25.2.4 The renegotiation process
The freeze idea is just a fantasy, designed to help us cope with our fear of closure. But we cannot fearlessly close the requirements phase unless we know there is some renegotiation process available. That's why agreeing to a renegotiation process is the last step in the requirements process.
Working out the renegotiation process is also a final test of the requirements process itself. If the requirements process has been well done, the foundation has been laid for the renegotiation process. The people have all been identified, and they know how to work well together. They have mastered all the techniques they will need in renegotiation, because they are the same techniques the participants needed to reach agreement in the first place.
25.2.5 The fear of making assumptions explicit
The agreement about renegotiation must, of course, be written down, and this act itself may strike fear in some hearts. Another way to avoid ending requirements is to avoid written agreements at the end of the requirements phase. Some designers are afraid of ending requirements because the explicit agreements would make certain assumptions explicit. An example may serve to make this surprising observation more understandable.
While working with the highway department of a certain state, we encountered the problem of what to do about a particularly dangerous curve on one of the state highways (see Figure 25-3). In an average year, about six motorists missed the curve and went to their death over a cliff. Because it was a scenic highway, it was neither practical nor desirable to eliminate the curve, but highway design principles indicated that a much heavier barrier would prevent wayward cars from going over the cliff.
pastedGraphic_2.png
Figure 25-3. What should be done about this dangerous curve?
Building the barrier seems an obvious decision, but there was another factor to consider. Perhaps once every three years, with a heavy barrier in place, one of these wayward cars would bounce off the barrier into a head-on collision with an oncoming vehicle. The collision would likely be fatal for all involved.
Now, on average, the number of people killed with the barrier in place would be perhaps one-fifth of those killed without the barrier, but the highway designers had to think of another factor. When a solo driver goes over the cliff, the newspapers will probably blame the driver. But what if a drunk driver bounces off the barrier and kills a family of seven who just happened to be driving in the wrong place at the wrong time? The headlines would shout about how the barrier caused the deaths of innocent people, and the editorials would scream for heads to roll at the highway department.
So, it's no wonder the highway engineers didn't want anything documented about their decision not to build the barrier. They were making life-and-death decisions in a way that covered their butts, and they could protect themselves by taking the position, "If I never thought about it, I'm not responsible for overlooking it in the design." And, if it was never written down, who could say they had thought of it?
25.3 The Courage to Be Inadequate
Most engineers and designers react to this story by citing similar stories of their own to prove, yes, indeed, there are decisions it's better not to write down. We believe, however, this kind of pretense is an abuse of professional power, an abuse not necessary if we remember the proper role of the requirements process.
It's not for the designers to decide what is wanted, but only to assist the customers in discovering what they want. The highway designers should have documented the two sides of the issue, then gone to the elected authorities for resolution of this open requirements question. With guidance from those charged with such responsibilities, the engineers could have designed an appropriate solution.
But suppose the politicians came back with an impossible requirement, such as,
The highway curve must be redesigned so there will be no fatalities in five years.
Then the engineers would simply go back to their customers and state they knew of no solution that fit this requirement, except perhaps for a barricade preventing cars from using the highway. Yes, they might lose their jobs, but that's what it means to be a professional—never to promise what you know in advance you can't deliver.

The purpose of requirements work is to avoid making mistakes, and to do a complete job. In the end, however, you can't avoid all mistakes, and you can't be omniscient. If you can't risk being wrong—if you can't risk being inadequate to the task you've taken on—you will never succeed in requirements work. If you want the reward, you will have to take the risk.