Software development is hard. A lot of people like the idea of couching this difficulty in a form of explanation by analogy. The most common comparisons are generally the most facile and glib, and more often than not, fail to really say anything essential about the nature of this discipline that some believe is an art, others engineering or science.
Architectural and construction linkages abound. For the most part, these are woefully misguided. Sure, software developers can learn from builders and architects. But that does not mean that what we do is anything alike. The notion that code can be treated like units or bricks is seductive but wrong.
Another popular metaphor - one that's getting renewed attention - is that programming is gardening. I actually like this one a lot better because I think it gets closer to a state of mind that's necessary when trying to create and grow successful software. But (depending on what type of gardener you are) it's also far too easy to imagine this taken to its logical extreme of festering idiosyncrasy. It says very little about the constraints and forces of software production.
These metaphors are all cast in a positive context, emphasizing the constructive, structural/functionalist aspects of development - the plan, the process, the procedure, the way takes pride of place. Perhaps it gives people comfort to apply familiar and mundane process analogies to a frightening realm where uncertainty abounds.
There's really only one deeply accurate metaphor in software development - unlike screeds of construction and gardening comparisons, it can be understood in terms of day-to-day practice as well as abstraction.
I'm talking about Technical Debt of course. Debt is an extraordinarily accurate metaphor for describing the unique problems of software development. Unlike functionalist process babble, it is objective - it can be thought of as a thing that a project has. Everyone knows what debt is, and likely, has some experience of it, so this explanation can be understood without requiring particular specialist knowledge of programming.
Like a financial debt, the technical debt incurs interest payments, which come in the form of the extra effort that we have to do in future development because of the quick and dirty design choice.
It really is accurate - even down to that horrible feeling in the pit of your stomach when your debts start to spiral out of control.
Paying back the debt is time consuming, and requires <a href=/on-refactoring">special skills</a>. Often, the programmers who create the debt are ill equipped to deal with it directly. Breaking even requires talented people who know how to tell a story in symbols; who don't just understand the virtues of radical simplification, but actually have the fortitude to cut through the knots in real code.
Sadly, all too many projects I see are wallowing in technical debt, and most managers are willfully oblivious to its destructive and demotivating consequences. If you want your team to be happy and productive, you need to accept the fact that you are taking on debt, and provide your team with opportunities to pay it off. Encourage them to identify and analyze problems with entropy on a project, and find ongoing strategies to mitigate the problems.
Web projects in particular, can have very rapid release cycles, so there is great scope for ongoing incremental repayments.