Prototyping vs Iterative Development
The problem with rich, custom web applications is that the client often doesn't know what they want until you build it. Even then they probably don't know what they want, although they usually know that is wasn't what you built them :-) . . .
If a client comes to us and has a unique set of requirements, at the very least well work with them in a discovery phase to document a set of essential user stories and well document click by click the default, alternate and error paths for each story. If we are not comfortable with the usability of the solution or if usability is critical, we'll used to build a prototype, but these days we'll usually just build the site to a basic spec and then tweak it if the default implementation doesn't meet the clients needs.
If you think about it, a prototype is really a form of insurance. It is allowing you to capture a higher percentage of potential issues with a design before building the app in return for the additional cost of building the prototype. A clickable prototype won't capture all of the issues, and you can capture some of the issues with whiteboarding, comps and wireframes. The decision as to whether to prototype a screen or a flow depends on the likelihood of there being issues that it would pick up, the additional cost of the prototype and the cost of making the changes to the app once it is done.
I generally see two broad approaches. One is to prototype as much as possible and then to send the project out to be built. The other (that you see in many agile shops and that I think is becoming more common these days) is just to build a sensible first cut based on a fairly lightweight description of the app and then just to refine the actual working application itself. At SystemsForge, mostly we'll just build an app for a fixed bid based on a straightforward spec and then we'll just modify the app as required on an hourly basis. As such our approach is more like the progressive refinement of the final app than the "prototype everything upfront" approach. I tend to like this as it has a number of benefits. Firstly, we never build anything the client isn't going to use, so the "waste" in production terms is low. Secondly, even the first cut works, so at any time the client can go live with a working application if they run out of time or money. We can then just add progressive enhancements over time. Thirdly, because we generate our apps, we have a default way we tend to build things anyway. If someone wants to add or remove functionality within our model (add properties or validations or relationships), we can add that very quickly, so the cost of change is very low. If the client wants us to make a screen or object work in a way that is outside how we usually do things, it's going to cost as much to do it now as later so we're just as well to give the client something that works the way we usually build things and then once they've clicked through the working app they can make an informed decision as to whether it's worth spending the extra few hundred dollars to customize the way that the screen works for their app. Of course, the reason we can do this is that our cost of changing the applications is very low and we're comfortable enough with the architecture of our apps that we don't mind making change after change after change and just refactoring to make sure the overall design stays clean.
What are your thoughts on prototyping vs. iterative development?



When I was writing software for banks, and then later for doctors, they couldn't give a care if it actually worked, just that it looked pretty. So in that industry, prototypes were king and rough apps were almost useless. (Someone always got hung up on the look and feel, no matter how many times we said that it wasn't even beta-quality.) Incrementally adding features was similarly frowned-upon, as if a placeholder for every single feature wasn't in the prototype, someone always had a hissy fit.
But now that I'm doing software for manufacturers, they are all about making sure that it works and couldn't care less about how it looks. (These are people that used green-screen dumb terminals for 20+ years.) Prototypes are now useless, and rough-cut working apps are the only way to go. Incremental feature development is how the last 80% of the app gets done, because what they initially envisioned was probably only the first 20%.
I think you need to be flexible enough to figure out which method your clients are going to respond to best when you first sit down with them. I generally ask flat out: "in two weeks, would you prefer to see something that looks like what you are going to get but doesn't work at all, or is really ugly but works roughly well?".
For my purposes, this approach has been sufficient to squeeze out requirements that the client didn't even know s/he had. I think this lines up pretty nicely with your second school of thought and it's worked for me.
@Tom, It is POSSIBLE to do both - question is whether it is a good idea, how far you go in refining the prototypes, etc. I'm tending now towards not prototyping (as in throw away prototypes) unless the functionality is really unusual/badly understood as I think it's often more efficient to be building something real and progressively to refine it. Also, note distinction between mock up and prototype. I agree mock ups upfront often make sense, but I'm starting to question the value of working prototypes that will then be thrown away.
@Rob, To me the distinction is between things you build and throw away vs. things you build and then refine. I think on the whole the trend in agile projects is towards progressive refinement rather than creating elaborate prototypes to be used as part of a spec to hand over for the programming phase.
@John, Effectively that's what we have. Because of the low cost of changes, we create a rough cut of the working app and the cost of change is low enough to be cheaper than the cost of prototyping and then throwing away the prototypes.
We may have do disagree on that one, but the disagreement is purely semantic (how "prototype" is defined) and therefore not germane. I won't propagate the argument since I think we agree on the larger point. :-)
That said, I also get that there is a place for paper sketches, for spikes to try alternate approaches and for prototyping some bits and pieces of badly understood functionality using code that may be thrown away. It isn't one or the other, but I do find myself tending towards "just enough" design upfront now. I still see people in the CF world trying to prototype an entire application and then to hand it off to the programming team, and in my experience, as the app gets more complex you're better just to iteratively knock out a couple of stories at a time rather than trying to specify the entire app and UI with really elaborate throw away prototypes.
Too much will change throughout the course of development to pretend that mockups done at kick-off will remain as an accurate portrayal of what you'll get in the end. Accept them as representative and move on quickly.