I'd hazard a guess that most companies develop software in a manner somewhat like this: they come up with a short list of features, break those down into a whole bunch more smaller work units, assigning those to some programmers, and then go back and review the database every so often to see how many of the work units remain to be completed.
Now, for the most part programmers are good people. They're interested in the project; they want to do a good job and make something easy and fun to use. So what goes wrong? Why do most applications ship with glaring bugs and obvious usability issues?
Here's why: Everything starts to revolve around this work unit database. Near the end, emails go out to the programmers saying, "I see you still have six work units left. Will you be able to get all those finished by Friday?" As the project moves forward, additional work units are added for new features or bugs. More emails go out. Eventually the project gets thrown to a tester, who enters dozens more work units. The programmers, faced with a long laundry list of items and a deadline, starts to cut corners. "OK, this item says we need to add a State Last Worked In field to the form. I know we're eventually going to need a Zip Code too, but I don't have time to worry about that; I have 15 more units to finish by Friday!" So the program goes without the zip code field. It goes back to the testers, who look at the list of completed work items; yup, there's the State Last Worked In field, looks good. Nobody's told the testers exactly what the purpose of the application is, so they don't know that a zip code needs to be there. Finally, all the laundry lists are complete, the testers sign off on it, the application ships. And customers look at it, scratch their heads, and say, "Why on earth didn't anyone think to put a zip code on that form?"
So what can be done to break this cycle? Well, the various methodologies that call themselves Agile have some ideas.