William Crawford writes, "Up front planning will help you get much closer to where you want to go, but iterative development, prototypes and a willingness to chop down trees (code) will get you to the best system in the most reasonable amount of time."
A year or so ago I got the refactoring religion in a big way, and I've been periodically tearing through my company's codebase dealing with the issues that had been put off for another day. It's an interesting activity the first couple of times, because, by definition, a refactoring means that the system works the same way when you're done as it did in the beginning. Of course, I usually cheat: I refactor when I suspect I might want to make changes in the future, and where the refactoring will make it easier for me to do that. I've even been known to break the cardinal rule of Doing It Right and refactor as I add new functionality, rather than before.
The interesting thing about refactoring in this case is that it's led the product in question towards a more self-consistent architecture than it would otherwise have had, even though I did a large amount of up-front design work on the current release, which is itself the fourth major iteration of the package (and presumably I'd learned a few things on Iterations 1-3). Of course, if I hadn't done the up-front design I wouldn't have had a stable framework to refactor in. If I'd built the system up function by function, I suspect the overall result might have been the same, but it would have taken longer to get the initial code working, and the refactoring process would not have been trivial (although one might say the whole fourth version was just a big refactoring of the third).