Saturday, September 06, 2003

The Grapevine Metaphor

Building a Bridge

Software development is a young industry. The complexity of today's software challenges has far exceeded the maturity of the programming discipline. For many years, we've tried to reign in the chaos by using traditional engineering practices.

The usual metaphor is bridge-building: You plan. You plan some more. You plan for every possible contingency. You build foundation. You build the bridge. You test it for structural soundness. You paint it. You throw a big party, and you let cars drive over it. Stray From This Path, and Disaster Will Surely Follow.

What we need to recognize, first, is that even bridges aren't always built that way.

The Golden Gate Bridge is an example. During construction, engineers ran into numerous difficulties surrounding the construction of the south tower. The sandy Bay floor, rough currents, and even ships lost in the fog presented potential dangers to the viability of the construction work, and the safety of the crew. What did the engineers do?

They paused. They thought. Then, they improvised. They designed, built, and lowered a sealed "fender" around the area. Then they drained it, poured the foundation, and went on with their construction. (There were certainly dangers remaining, but they acknowledged those, and finished the work.)

Recently, the Richmond Bridge experienced a retrofit (and some traffic delays). Earthquake safety improvements, of course. Why didn't they build it for earthquake safety in the first place? They did, I'm sure. But we have learned new techniques since then, and we want to apply those, without having to rebuild the entire bridge.

I cannot even use the bridge metaphor to describe Extreme Programming. If I did, I'd claim that we could apply some of the paint first (e.g., GUI look-and-feel). That we could--and would--try driving a few cars over it (i.e., acceptance tests), knowing that the first set would fall into the bay. That we could build a temporary foundation, and swap it for a new foundation when necessary (e.g., flat files vs. RDBMS). You would back away from me, slowly, one eye on the door. You certainly wouldn't want to drive over my bridge. The problem is not that XP is a crazy approach to software development, but that we've been using the wrong metaphor to describe software development.

Growing Grapes

Software development is quite different from bridge-building. All software, despite our best efforts to plan out every detail, grows organically, like a grape vine. You can let it get out of hand and take over your whole yard, or you can prune it and shape it until it grows sturdy and drought-resistant.

The industry is beginning to learn how to contain the chaos. Not by trying to plan out the exact direction and length of each root and branch before we even plant the seed, but through vigilant care and pruning.

XP is a set of necessary tools, carefully assembled and tested by numerous experts.

The entire team of engineers, managers, and customers communicate frequently. We know what the software should do, and we know what progress has been made.

Very short iterations keep the team, and the software, on track. During each iteration, we build those features that the customer has designated as the highest-priority. Intuitively, you may see that this is an excellent approach for a project in its maintenance stage. But this rapid feedback is also a powerful tool for building software from scratch. The customer can alter course at any time. Imagine how powerful that is in any dynamic, competitive field.

We have automated unit tests, and we write them first. Why? Unit tests exercise an object's interface, and writing them first is an excellent way to define and document the intended behavior of that interface. We know that we're done with part of the implementation when our new test passes. Then we write another test. When we've completed a task, we run all the unit tests for all the objects in the project. They all have to pass, otherwise we broke something else.

If we do break a test, we are responsible for fixing it, immediately. We have the ability to change any line of code in the project. Chaotic? Not at all. We still have all those tests to keep us on track. We also have a simple coding standard to follow: Similar naming patterns and one indentation style allow us to quickly understand code written by other teammates. We reserve our creativity for problem-solving, not trivial differences in preferred brace positions.

The test-first approach is difficult to appreciate for the first two or four weeks of a new project. Programmers without test-first experience usually dread writing tests. It feels like excessive overhead. But tests are an investment. We spread the cost out over the life of the project, rather than tossing it out entirely in order to meet a delivery date. And we begin to reap rewards after those first few difficult iterations. I am always amazed by how quickly the growing network of automated tests can spot a new bug, particularly when a change is made to an object that "shouldn't affect anything else." Without tests, that bug could lay hidden for months, perhaps to embarrass us when the software reaches an end-user (e.g., the people trying to use your web site). Tests usually pinpoint a bug that would normally take hours to find with a debugger.

As a programmer, I'm addicted to the test-first approach. I can write code rapidly, confident that our all-encompassing suite of tests will catch most mistakes that get past the compiler and the programming partner sitting next to me.

We have refactoring skills, the sharpest of software pruning tools. A viticulturist will often cut off some young grapes, allowing the vine to concentrate its productive energy into the remaining grapes. Similarly, the skilled programmer can reduce duplication as a new task is implemented, thus simplifying the design. In turn, simple design makes the next task easier to implement. As the project progresses, the software becomes easier to extend.

Wait. Stop! Did you catch that? As the software ages, it becomes more flexible.

In fact, we are always working to improve the code, or at least to keep it from getting worse. As it ages, it may truly become better, like a gnarly old Zinfandel grapevine.

No comments: