Here's something you should do.
Typically, when I'm going to start a project I work out a document that details the goal of the project. This gives me something to work with initially. If this project is for a client, we'll go over the document, and make changes as needed so that it will reflect what they want, initially.
After building the document I typically will build some use cases for project, based on the document. This gives me some idea as to how I want the application to behave, and how I will probably structure it as well. The other thing is that when building a use case you will typically find other optional or alternative use cases that you hadn't thought about. Note that optional != alternative. An optional use case is one which isn't required, but can be added without conflict. An alternative use case is one which when added precludes the use of another use case.
So you say to me, "But Washu, we've done all this work and still don't even have a single line of code to show for it!" This is true, but I have an idea now as to how the application should work. This is important, especially for the next stage, which would be prototyping the application.
A prototype, for me in many cases, is a throwaway prototype. Now, after the recent topic on the forums, I started looking at my older projects, and noticed that I tend to use a throwaway prototype a lot. The thing is, the prototype may have been thrown out, but artifacts developed during it's inception are not. Those artifacts typically go into a repository for reuse, either in their current form, or in a refactored form. This prototype is a good way to get client feedback, just be very sure that they understand that it's a prototype and that it has bugs, and is not representative of the final product. You must be very clear on that point, otherwise they can (and will) misinterpret your prototype.
The prototype is also useful because it will typically reveal some optional or alternative use cases that I did not think about in my initial design. You find these both through client feedback and through just the development of the prototype application.
Developing a Prototype
Gotta be careful here, you must always remember that this IS just a prototype. Spending too much time on it will mean you'll have to rush for the real thing. The goal here isn't to build a fully functional application, but to build something for the client to give you some feedback on.
First things: Use TDD. This will save you in the debugging arena. While I've seen arguments for and against TDD, I will say this: I have never been let down when using it. It has saved me from making stupid bugs, and it has saved me in finding some of the most complex and horrifying bugs you can imagine (Things like the program reporting the incorrect amount of memory usage when the day ends in a 6 and the week was odd, and yes, that was a real bug).
Secondly, build a design up front. I typically do it from a high level down, usually designing how the systems interact, then going lower from there. I, however, never drop below the component level. I have reasons for this, but I'll get to that later. Note that the design you come up with will evolve as you write the prototype, and that the components you build will end up in the repository. Those components, and even entire systems if you can, are known as artifacts. The advantage here is twofold, firstly you are getting feedback from the customer, which will help to direct the development of the final application. Secondly, you are building components that will end up being used in the final application, and if you're lucky, in other applications.
Now, I mention that the prototype shouldn't have a whole lot of time spent on it removing the bugs. That isn't to say that you shouldn't remove bugs, it's just that you shouldn't attempt to work out all of them. It should be mostly wrinkle free though, especially if you have practiced TDD and refactoring.
Anyways, that's it for now. Comments, as always, are welcome. Next time I'll focus on some issues with upfront design that you should avoid.