The PragmaticProgrammers have a great analogy for software development which I somehow overlooked (and/or probably forgot) in their similarly titled book. They discuss “software as gardening” in an interview here. An abridged quote:
Software is much more like gardening. You do plan. You put the big plants in the back and short ones in the front. What happens? This plant gets a lot bigger than you thought it would. This big plant in the back died. With a garden, there's a constant assumption of maintenance. We want people to view software as being far more organic, far more malleable, and something that you have to be prepared to interact with to improve all the time.
This interview also references a story of theirs I like to retell, relating to a contradictory law:
As an anecdote, on one project Dave and I were implementing legal requirements in code. These were actual laws that had been passed. We got about three quarters the way through it and realized that the law as stated was wrong. It was inconsistent. If you read through the law one way, it said something had to happen. But in the next paragraph it contradicted itself. Nobody had caught it up to that point, because nobody had tried to do a detailed implementation enacting this legal requirement. This mere mechanical act of coding actually catches bugs in the real world. If you dismiss it as just a mechanical translation, what are you going to do? You find genuine requirements problems while coding. You've got to be able to react and adapt to them.