Metaphors are used by software engineers to help users relate to the software that they're creating. For instance, the name "desktop" for the screen Windows and other systems present to the user comes from the desktop metaphor, which was designed originally to help users understand the nature of the two-dimensional space displayed on the screen. Metaphors are also used by software engineers to talk to one another. Many computer-science terms stem from metaphors, such as structures, trees, tables, indexes, et cetera.
However there is a more overarching metaphor that applies to all software development, encompassing everything from the initial conception of the users' needs to the final, tested and installed product. This metaphor is mostly unused by software engineers when talking between themselves, because for the most part (since it is our profession) we don't need to resort to metaphor to describe what we're doing. The overarching metaphors are used to communicate what might be difficult to do and what might be trivial.
The problem is when you compare software engineering too strongly with its metaphorical counterpart, people start focussing more and more on the tangible metaphor rather than the hokus-pokus of software.
I am going to take this time to describe the current most-popular metaphor used today and explain what problems it has caused. Then I'm going to present a better metaphor and tear it down as well. Ultimately my conclusion will be never to adhere to a metaphor too strongly lest you foster misunderstanding.
Today we use the "architecture" or "construction" metaphor of software development. Indeed, the very terms "software engineer" and "software architect" come from this metaphor. We often say that we are "building" software. Software runs on "infrastructure". This metaphor has shaped the terminology we use to describe these ideas.
The metaphor owes its strength to the age and wisdom of building structures. Humans have been building shelters (or at least finding and improving them) since before recorded history. Though not everyone is a civil engineer or a design architect, we're generally very good at looking a building and deciding whether or not it was well constructed. Even though not everyone can build a house, nearly everyone lives in some kind of man-made construction. Therefore drawing an analogy to construction literally hits home with everyone.
Everyone in the software engineering business knows that spending an extra hour designing a program will save an extra week of coding time. This came from the construction metaphor. Architects and civil engineers spend as much time as necessary poring over every minute detail of the construction plan before even considering moving forward with it. After all, if they get anything wrong the building may not last for hundreds of years. Or worse yet it may collapse and kill everyone inside. Indeed, if everyone approached software design with the idea in mind that flaws could prove fatal then we'd surely try to go the extra mile to make sure everything is perfect.
Because of this attention to detail, the metaphor draws a lot of strength from the higher-ups, whoever they may be. They like to think that we programmers are doing everything we can to construct perfect software that will last forever. And who can blame them?
The metaphor is flawed in many subtle ways that lead to a great deal of frustration when dealing with people very far removed from software development. While I could go on for several pages enumerating them I will stick to the most obvious and problematic.
The concept of "maintenance" as it is used in software engineering is the complete opposite of the equivalent term in civil engineering. Once a building is erected it will slowly degrade by no fault of the engineer who designed it. It's simply a matter of fact. Things in the real world degrade over time. This is not the case with software. If there is a problem being observed with software, it was not "damaged" or "corroded" by some outside force. Rather the one who designed the software forgot that particular detail and no one noticed until now. Software "maintenance" is the programmer changing the logic and design of the program. That is nothing at all alike real-world maintenance.
It takes a great deal of time and effort to change the design of a physical structure once it's built, or even if it's half built. Therefore you have to completely understand what your customers want and tell them, "OK. No more," before the first hole is dug. Nothing could be further from the truth with respect to software writing. New-but-similar requirements and even most new-but-completely-unforeseen requirements can be added to a piece of software in a matter of hours. In fact we, as diligent software engineers, specifically design our software in such a way that adding, removing and changing details is as painless as possible. Now, obviously there is a limit to how many and what kind of changes that can be made to a design without needing a lot of effort, but that threshold is much, much higher than most would imagine.
This misunderstanding of software is so pervasive in the minds of non-software engineers that often teams are specifically told to go to great lengths to avoid "hard coding" things into a system. The act of avoiding hard coding anything is called "soft coding" and it is nothing but trouble. Nothing is more prone to error and bad design (and, ironically, inflexibility) than soft coding, at least as far as I'm concerned. The separation of logic (i.e. code) and what the logic works with (i.e. data) is good enough to guarantee the least amount of effort needed from each party involved (most of the time).
To reiterate my point (which I really can't stress enough), consider the effort needed when I added a completely new piece of functionality to KevBot. KevBot was never designed to do anything remotely similar to a Markov chain. Its data structures aren't designed for the deep searching required to build it. I had never written a Markov chain algorithm of any kind before. In fact, we had only covered them briefly in my intro to AI course in university. It took about an hour, maybe an hour and a half, to get it up and running and live and interacting with users. Same deal with this website. About two hours from having an idea to having a full site written up in a language (PHP) I had never used or seen before.
Now, I'm not boasting my ability or claiming that KevBot or this website are at the same level of complexity as most business applications; rather I'm claiming that software is highly malleable, with previously inconceivable features added in mere moments. I'm claiming that had one adhered to the architecture metaphor, one would think that this kind of thing would take weeks or even months to complete. That is because the metaphor is flawed.
A better metaphor for software engineering that clears up these important misconceptions is Lego. Lego, the children's toy of colourful little blocks that fit together is more similar to software development than architecture. And I can prove it.
First of all, given enough of it, Lego can build anything. Right there, Lego is more robust than civil engineering. Name everything you can do with a house. You can live in a house, and that's pretty much it. Everything else you do in a house is done with supplements to the house itself like beds and televisions. Civil engineers don't build beds and cool robots. But you can build beds and cool robots and much more out of Lego. Just like how you can do more than just build websites with software. Software and Lego can both do anything.
Lego requires careful planning, in fact all of the careful planning that civil engineering requires, to make something right. Just like construction, every hour spent planning saves days once you start snapping the pieces together. Lego blocks also don't degrade over time. If you build something out of Lego and it stops working, then it's because you didn't squeeze the pieces together tightly enough, or you didn't build it structurally sound enough to keep from falling apart during use. If it breaks, it's because it was always broken, just like software.
Anyone can use Lego. You don't need a degree in Lego science to build a rocket ship with Lego. You don't need 15 years of experience designing cool Lego toys in order to make a neat robot. Just like programming (and very, very much unlike civil engineering) Lego is very easy to pick up. (Not that this is necessarily a good thing, since you generally don't want to set up a production Lego construction that was assembled by someone who's never used Lego before. Just like software design!)
Changing a Lego construction is easy, too. You want to add a third arm to your cool Lego robot? Just snap it into place! You don't like this colour of block? Take it out and put a new colour in. It's that easy. Just like software.
But even this metaphor has issues. Building an algorithm isn't anything like snapping colourful bricks together. It's not that easy. Also, the importance and difficulty of debugging is completely lost in this metaphor. It's generally very easy to see what part of a Lego robot is flawed by looking at the broken wreckage. Software not having physical form makes this much, much more difficult. Lego also requires a surplus of bricks to create something, often requiring the cannibalization of previously-built cool Lego robots to get them. Software has nothing like this. Code has no physical form, after all.
No matter how cool Lego is (it's very cool), it can't serve as an adequate metaphor for software development. It's not Lego's fault, though. This is the problem inherent in all software metaphors. Just like how no one has a physical "taskbar" or works by moving "windows" around on his desk (the "desktop" metaphor). No one metaphor is going to fully explain any discipline. It's not that we shouldn't try to use metaphors to help describe what we as software engineers do, it's that we shouldn't let these metaphors drive the nature of the discipline.
Software engineering is software engineering. It's not civil engineering, it's not architecture, it's not Lego. Never forget that.