There are lots of analogies for writing software. Some people compare it to architecture (is Art Vandelay writing programs on the side?) and others compare it to bridge building. I'm going to compare it to building a railroad in a remote, harsh environment. What brought this to mind is that I've been reading a book by David McCullough called Brave Companions. It is a set of 17 essays on people (and some places) you may not be familiar with but who are important in history. One of the stories is about the building of the railroad across the Isthmus of Panama. As Mr. McCullough develops the story of how difficult a project it was, I started to see parallels between what the builders faced and how a software project is run. Not that we have to deal with danger, disease or hard physical labor but the methods of planning and executing the plan are similar.
First off, there was no support system in Panama for the men (construction workers and engineers) and the machinery (no supplies or repair facilities) so before they could even begin, they had to set up a support base. People had to eat and equipment needed to be sheltered from the elements. Managers like to talk about "building up the infrastructure" and engineers like to talk about building up the "support network" but it's all the same idea - you end up spending as much (if not more) time making things to support the work as you do spending time doing the work itself. In a lot of engineering projects this involves designing a testing system so you know what you're building will work correctly or safely.
Another similarity I noticed was their need to build the railroad so they could build the railroad. This sounds silly but what I mean here is that they used the railroad itself to transport equipment and men to the work area. This involved quickly building a not-ready-for-prime-time track into the wilderness to get rails, ties, ballast (the stones the track rests on), spikes and men that was just good enough to allow a locomotive and cars to run as far into the jungle as possible. Then, in parallel, they would go back and improve the track to bring it up to the level of what the railroad needed to be to operate commercially. We do similar things in our programming. We often write ugly, inefficient code just to get something running so we can test it and to enable us to write other code. Then we go back and make the code more efficient. We add more error checking and handle problems better. We make the user interface look nicer and make it easier to use. One fellow engineer used to joke that when you used the early versions of our software and firmware, it wouldn't run correctly unless you wanted it to work. For example, you had to know that only certain things would work or that certain values had to be entered that would work. Then we would go back and make it more robust.
They finally finished the railroad and it worked well for a long time. It was the most profitable railroad in the world for a long time. They could charge whatever they wanted because there was no competition. Another analogy between the railroad and a software program is the need for maintenance. You might think that once a program is written, it runs forever but that isn't true. The underlying operating system changes. The data the program works with changes. And the people who use the program think of new things they would like to do with the program. A good program is built so that it can be upgraded. Here is an interesting link about the Panama Railroad.
[Updated, Dec 3, 2008: It turns out that one of my favorite blogs, Coding Horror (it's in my list of "Other Blogs"), has a post about variousg analogies used to describe writing software (or Software Engineering as some people say). It starts by listing some of the other analogies and then adds another, programmers as farmers.]