Do you sometimes struggle in explaining your work to others? Especially at project planning time, I sometimes reach for metaphors to explain why estimating can be hard. Here are a few of the metaphors I've used in the past, and a few reasons they aren't adequate.
Building a house or bridge
This is a common analogy, and one often used by those that believe programming is 'engineering'. It's true that you can break the problem down into smaller pieces, then plan constructing the pieces. Repeat this cycle, going into ever greater detail, until you have your 'plan'. In this way, construction is similar to traditional 'waterfall' methodologies. There are similarities to 'agile' practices, too. A house is built iteratively-- you pour the foundation, then put up the framing, then the roof, etc. At any point along the way you can evaluate and make small changes as you go.
But.... a building is a lot more like other buildings than one computer program is like another computer program. We've been building houses and bridges for centuries, and there are only so many variations among them. Programs, on the other hand, have only been built for about 50 years and they have a lot more variables that can change. Programs also have temporal issues to deal with-- the order of things happening must be considered. (A bridge, on the other hand, mostly just stands there and lets things go over it.) For these reasons, I don't usually like this analogy.
Writing a book
In both cases, you're using text to build your deliverable. You have to break things into smaller pieces (classes, layers, etc. in software, chapters in books). You follow style guides, and have an ordering of things. All the little details you conjure up have to be consistent. In books, your characters should have past experiences that 'fit' in the context of the story. In programming, you need to make sure the data you need is available to all facets of the application that require it.
But.... I think writing a book is probably a lot less restrictive than programming. You have more freedom in the way you express things, for instance. (I don't think most editors are as picky as compilers.) In some ways, this makes programming easier-- once you have your goals defined, the ways you can go about achieving them are narrowed down. The degree of creativity is high in both cases.
Painting a picture
Painting a picture can be like programming because you're making something creatively, and you're building it in a sort of iterative manner. This is somewhat like the book argument, except the painting seems a little less constrained in places. You can choose your medium-- oil paint, water color, chalk, etc. much as you can choose your implementation language in programming. Programmers can also bootstrap projects by copying the work of others. ('Hello World', anyone? It can be seen sort of like paint-by-numbers.)
But.... paintings don't have to be exact. Their 'goodness' is found in the eye of the beholder. Oh, if only programs were that way!
Assembling a child's toy
Have you put together a bigger toy lately? They usually come in a cardboard box with about a hundred different parts in it, with an instruction sheet written in half a dozen languages. The assembler (you) reads the instructions and attaches part A to part B. The instructions (like documentation in software) are sometimes good, sometimes not. Sometimes you have to refer to a picture of the toy to see how to do it. This is like studying design patterns or reference implementations. In today's programming world, (especially Java) we have a lot of frameworks that make programming seem like this.
But... You never really fabricate anything by yourself in the toy scenario. You're using parts somebody else made. So I don't think this one is exactly right, either.
Those are some of the metaphors I've used. If you have any better ones, please share!