I prefer the 'worse-is-better' approach, with very little design up front. Instead, I make a list of things the program must do. Then I break each thing into tasks, and arrange them in order of importance.
in reply to Coming up with code design
It's a lot easier to design something well if it's small and if you actually need it right away. (It's also a good idea to cultivate the habit of writing unit tests *before* you implement something.)
If you do this consistently, you'll maximize the value of your programming time. Doing the unit tests will help you keep things running smoothly.
It's hard to guess what you'll need before you start programming. It's a lot easier to change things if you work on only one task at a time and if you have a baseline that will prove that your changes didn't break anything.
That doesn't mean you don't do design, but it acknowledges the fact that it's hard to do design perfectly the first time for anything but the smallest programs.
(If this all sounds familiar, yes, I'm ramping up for my XP talks at OSCON.)