The processes I've talked about up until now generally focus on the predictability of what will be built - that is, if you really know what is wanted and needed down to the last detail, then you can use one of the planning-heavy processes or methodologies to build it effectively and predictably. For some software like the space shuttle software, this is a great thing to do: Plan it out, design it to the last detail, prove everything you can about it, then build it as carefully and deliberately as you can.
But progress and business won't wait for that. Businesses thrive by being agile - adapting to changes rapidly. And if you are building something that has never been built, then you'd better be prepared for surprises - if for no reason than if you happen to come up with something great that wasn't what you were planning, you'd be smart to exploit it rather than throw it away.
The other issue is that the people who are best at building software that has never been built before are usually quite talented, creative, and intelligent. It is not going to work to design out to the last detail something that has never been built before and then ask talented, creative, intelligent people to build it but not react when things go wrong or a better design or approach pops up. They will not work for you if you do this.
Think about how bridges are designed and built. Designers first come up with a detailed plan for the bridge based on geological investigation, centuries of experience building bridges, and careful, precise mathematical analysis, an analysis made possible by the nature of the physical world and science. Then, another company is hired to apply physically skilled construction workers and unskilled laborers to construct the bridge according to a relatively predictable schedule and known costs. Many would like software to be like that. It cannot be because we don't have the physical world and experience to make things predictable - you need them both. We have neither.
In response to recognizing that what we are doing is unpredictable and requires very smart people, the software community has developed a group of processes or methodologies noted for being lightweight and adaptable. Such methodologies are sometimes called agile methodologies.
The best known of these methodologies is called Extreme Programming. It exemplifies the agile methodologies in all but one particular way, which is that it does not emphasize adapting the process itself to the team and circumstances as much as other agile methodologies do.
Extreme programming expounds practicing to an extreme activities that other methodologies promote.
Code reviews by others are considered an important part of ensuring quality early in the implementation of a program. Therefore, Extreme Programming requires that developers work in pairs, sitting at the same computer all the time with one then the other controlling the keyboard and mouse so that the code is being continually reviewed, not simply periodically.
Testing is important to quality, and usually it is performed toward the end of a project when it is almost too late. Therefore, Extreme Programming requires that tests be written at the same time as the code or before, and that all written code must pass all its tests all the time. This way, testing is continuous.
Design is important to any piece of software. Therefore, Extreme Programming requires that design be part of everyone's daily business.
Simplicity of code and design is good. Therefore, Extreme Programming requires that the code in the current system be the simplest code that could possibly support the current functionality.
Architecture is the fundamental stuff of a maintainable and changeable system. Therefore, Extreme Programming requires that everyone with a stake in the software should continually work at defining and refining the architecture.
Short iterations and frequent integrations are good because they enable the team to see where the software is going, to see how users respond to it, and to adapt to newly learned requirements. Therefore, Extreme Programming requires that iterations be very short - seconds, minutes, and hours rather than weeks, months, and years - and that integration tests be performed several times a day rather than every few weeks or months.
Other agile methodologies build self-review into the responsibilities of each team, so that not only are the plans and designs for the software subject to adaptation, but so is the process itself. Extreme Programming results in quick turnaround for small additions and changes, so adaptation to what's learned can be immediate, and such a process keeps talented developers challenged and alert.
For predictable software - software that's been written dozens of times before or which is the result of some sort of detailed mathematical analysis - you wouldn't use a methodology like this. But for something never built before? Or heard of before? Or never heard of by you and your team?
I believe creating a completely new product is a hard concept to understand for someone who has not either developed software or been deeply involved with some creative activity. It seems that making software must be like designing and building a house, or a car, or a highway, or a TV, or a stove. Let me try to provide a scenario that might make it clear.
Suppose you wanted to design and build a gas stove, but no one had ever used gas to cook with before. In fact, assume that before this, all that had ever been used was a wood stove.
Here are some things you wouldn't know: Will you use the gas flame to heat a piece of metal on which the pots and pans will sit, and that metal will transfer the heat, or will the flame be applied directly to the pots and pans? How will you control the temperature? Will you require that people move their pans from places of intense heat to places of less heat? Will you provide a gas flow controller that will reduce the amount of fuel to the flame? Will you move the flame closer or farther away from the pan or heat transfer metal? Will the heat be a manageable temperature for all kinds of cooking or only for limited use? Will cooks be afraid of using gas? How will you get it into the stove? Will it be stored or continuously supplied? How will you control the temperature of an oven using gas? Will a stove designed this way be affordable? Will the stove explode? Will the gas smell funny? Will the stove need to be inside or outside the house?
There are thousands of questions like this in every software project I'm calling unpredictable, and I'm also claiming that almost all software projects are unpredictable.
Recall that I said that unpredictability is only half the problem. - That the other half had to do with the programming languages and tools we use which make it very hard to write software that isn't brittle. - And that the brittleness had only a shallow relation to cause and effect.
Writing a correct program requires enormous attention to picayune details written in a language designed for mathematical computation, not symbolic or business reasoning.
Because of that, design, proving correctness, and testing are required. Extreme Programming makes you test continuously. The Cleanroom Process makes you both prove correctness and test.
Programming is very hard work because in many ways, the stuff inside a program is too much like a complicated mathematical function that somehow does what you want, even when mathematics is not part of your game. Computers deal with bits, bytes, and simple logical and arithmetic operations on them. Most of the programming languages we use do not raise the level of abstraction much higher than that, though when designing software we hardly ever think in those terms.
I mentioned prototyping languages before. Those languages did raise the level of abstraction quite a bit. This made creating software a lot easier and quicker, and they were less prone to errors. In many prototyping languages, errors were assumed to be common and such languages provided easy mechanisms for programmers to decide how to deal with them or for programmers to decide how the programs would decide how to deal with them. Today, programming languages call errors "exceptions," and deal with them that way.
Languages like these could make a big difference today in how fast we learn and the satisfaction level for consumers. But over 10 years ago the computing world decided to give up on languages like those. They ran way too slowly. They were a little too big. Of course, now that computers are 500 times more powerful and 250 times larger than back then, maybe this wouldn't be as true, but computer science research and computing practice have both forgotten about these languages and approaches and, in some cases, essentially outlawed using or thinking about them.
Well, so we program in the dark ages - what of it? Actually, we've figured out a way around that too.
Because programming languages are too primitive, a large program is too complicated for one person to understand and get right, and there are too many bugs and other errors for one person to find and fix, and it's just too large for one person to get done quickly. How do you solve a problem like this? You have thousands of people work on it. This is called Open Source.
To understand how this works requires a little explanation. When you design, build, and sell a car and it's sitting in someone's garage, its innards and how it works can be - more or less - discovered by opening it up and peering inside. In fact, if something goes wrong with the car, maybe you can fix it yourself, or maybe you can take it to a repair shop where someone will fix it. Or suppose you don't like the shocks or fuel injection system. If you're real good, you can change those things or someone can do it for you. You could even install a nitrous oxide system if you wanted an extra 200 horsepower for short periods at a time.
In fact, just about everything we as consumers can buy has the property that there are plenty of physical things about it that a consumer can fix or customize or pay someone to do for them. Not so with software.
Imagine that you open up your hood and what you see is sand. Open up your TV - sand. Look in the back of your refrigerator - sand. Unscrew any access plate anywhere in your house - and it's more sand. Change or move one grain of it and - ka! boom! - it doesn't work anymore or does something you don't like such as show only the Home Shopping Network, heat up your ice cream, or make your car go only backwards honking the horn. Sounds a little nuts doesn't it?
But that's exactly what software is like. The software in a form that people have a chance to understand is transformed by the software maker into something only a particular set of computers can understand, and that's what you buy. Even if you were capable of finding and fixing a bug in Microsoft Word, you couldn't do it unless you worked for Microsoft.
Let's go back to the real world example. If the innards of your car were like software, then when it needed to be fixed, the original manufacturer would have to be contacted. They would prepare a new batch of sand, and that batch would replace the sand in your car.
Ask a software company why they want you to not even see what is inside what they sell and they will tell you that either it's too complicated for you to understand or that this way they can protect their trade secrets.
Both patent law and copyright law apply to software - this is more protection than the auto manufacturers have - so that can't be a good explanation. Cars are pretty complicated too, so that can't really be the reason. Maybe the clue is in the idea that for you to get anything changed about the software you need to go back to the software maker.
In the auto industry there is an aftermarket for spare parts, custom kits, instruments and tools for diagnosis and repair, and repair shops. We've got that for most consumer electronics, white goods, lawn mowers, houses, bicycles, musical instruments, on and on, and even computers. But not for software. The only aftermarket is for designed-in software customizations and fixing user configuration mistakes.
If you buy a book and find a typographic error, you can take out your pencil and fix it. If you find a similar typo in the user interface of a program, only the software maker can fix it. Sounds like they've maneuvered themselves into quite a nice place, don't you think?
Well, Open Source is out to change all that.
In Open Source, all the source code for a system is available for anyone to look at and modify for their own purposes. The source code is what the software makers turn into sand. In an Open Source project, the mechanisms for turning source to sand is freely available.
The source for the project is kept in a special, open place, and changes to the official source are loosely controlled by a group of developers and perhaps some governance process. This group of developers is dedicated to enabling the community to move the software along without hogging control of it. If anyone finds a bug and sends the fix to this group, the fix will be put in right away. If anyone makes an improvement, the same is likely to happen. If someone thinks they have a better way to do part of the system and the developers in charge don't agree, that someone can fork off the source and start their own competing project.
Typically, the Open Source project has an active community with mailing lists, a Web site, and email archives containing all the design and implementation changes. Alterations to the software are openly discussed and such discussions can be brought up by anyone. Usually some consensus is arrived at and changes are made.
Companies can take the results and by either adding functionality, providing support, or surrounding it with other software, make money from it - often as much as closed source companies do.
In an Open Source project, there can be tens of thousands of people who use the code and help fix it, and hundreds or thousands who contribute to its development. In any given day there can be hundreds of email exchanges about the software. The community itself is the support organization, and just about every question is answered by the community or by its archives.
Testing is continuous, integrations and releases happen just about every day. Design and implementation is done in the open on mailing lists. All the design decisions are thereby written down. Architecture, design, implementation, and testing are done in parallel by hundreds or thousands of people, not just by a pair or a small group.
There are two important things this accomplishes. One is that the fact that programming languages are backward doesn't matter too much to the project, because there are lots of people to share the burden with. And the direction of the software is subject to comment by thousands of people, and if there are severe disagreements, a competing project can start up from the same source base. This way, the process of finding out the true requirements for a piece of software never yet built can be rapidly discovered.
What I've been talking about is creativity in a hostile medium - making things that have never been made before using tools not suited for it. But we're doing a pretty good job. Creativity is a funny thing. It takes lots of practice and lots of whacks to get something right. A professional photographer will shoot many, many shots of the same subject, bracketing exposure, trying different exposure durations, moving the camera around, trying different angles, different lighting, different filters, different props if that makes sense. The results will be in a distribution - a few not so good, most pretty good, and maybe a few that are really great. Now all the photographer has to do is select the best ones and work with them a bit in the darkroom or on the computer.
The number of photographs taken to get some good shots can be staggering. For one piece in National Geographic Magazine using 22 photographs, the photographer took about 40,000 photographs - this is over a thousand rolls of film to select just 22 photos. This might seem like a typographic error or a fluke. Here is an excerpt from a story about another photographer, Joel Sartore:
The standards are incredibly high. For a photo story on Nebraska that ran øin the November 1998 [National] Geographic [Magazine], Sartore had eight weeks total to shoot, which he broke up into several one and two-week intervals over two years of time. Of the 31,320 photos he shot for the Nebraska story, only 16 ran in the magazine.
Once the film is shot, the best ones are selected and then the photographer works in the darkroom or with Adobe¨ Photoshop¨ to perfect them. We all believe the perfection part of the story, but we don't believe as deeply or appreciate the selection part.
Another example is filmmaking. The movie Apocalypse Now runs about two and half hours. To get those 2.5 hours, the filmmakers shot 250 hours of film. That means that for every hour of film on screen in the final version, over 100 hours of film were shot. Once the film is shot and selected, the work of perfection goes on in the darkroom, perhaps on a computer workstation, and then in the editing room.
When the poet James Dickey wrote a poem, he would sometimes do 500 drafts to get the right one. Great art is a process of making lots of things, knowing how to select the good ones, and knowing how to perfect them - making stuff, choosing critically, making some mistakes, being able to recognize them, and then being able to correct them.
When you design for the physical world, you design with it. Nature is your collaborator. Most product designers have the advantage of centuries of experience with artifacts in the physical world, and so they've had 500 drafts or 40,000 attempts in their experience base. Software is fiction, it is imagination. Not many rules apply. We are just 50 years into it and going as strong as we can.
But the software creation discipline hasn't gotten to the selection part yet - each methodology I've described operates under the assumption that someone can know what to build and that by either thinking hard or making small, incremental modifications, we can build the right thing. No other practice of art demonstrates the truth of this proposition. We can build OK things, but not great things. In only a small number of cases have we made a diversity of software and the selected, and in most of those cases - such as for text editors - the ones we selected were not the best.
And the software world has not yet figured out how to engage effectively in the design process the people we call "end-users." Almost all software is designed by software developers with no training - and not much interest - in how non-programmers will use it. These chapters in the history of software development are blank pages.
As time goes on, your process of product design will blend with mine - you'll have reality on your side for part of it and your imagination in the way for other parts. Before this, you've had the benefit of centuries to work out what people want and need, but now you need to figure out how to involve users from the start. If you've included software in your product before, you'll find that as you include more, you'll need to iterate, to produce diversity, to select, to hone, and perhaps to use the mob and not just your own developers. You'll find creativity working hand in hand with engineering. It will feel strange and you might feel like things are out of control. Relax - they are.
What we've learned in software so far is that you can build things out of junk, but that finding out what to build and how to best design it takes creativity - that is, lots of tries, working with the folks who will use the stuff in the end, and perfecting the best attempt. It's too bad building software isn't like building bridges. It's more like writing novels - maybe like writing science fiction.