An advantage of doing test driven development
I have mixed feelings about 'test driven development' (and I can't claim I've done much of it, especially not with rigor), but one subtle advantage of it has come through clearly even in my limited use of it: you actually start using your code's interface before you freeze it. This is important because actually using things remains by far the best way to refine their design in computer science.
Usually I started out with a general idea of what function calls and methods and so on my code is going to have, some broad and fuzzy vision of how it's going to work. More than once, the process of actually using this interface to write the tests has shown me that I am totally wrong. Actually writing code that talks to my code to be has rubbed my nose in the fact that the natural interface is something else, or that I can't stand some aspect of it, or there is too much repetition or indirection, or so on. The act of writing the tests prompt me to revise my planned interfaces, generally improving things.
Of course, you can revise interfaces at any time. But the advantage of TDD is that you can hopefully do this before you have any actual implementation code written, which means that there is much less inertia holding you back from doing it. If you write the implementation first and then discover that the interface kind of sucks, there is always this temptation to not revise things and live with a less than ideal interface because you already have working code and it would be a shame to throw it out and start over. (Especially because you may have other code that uses the existing interfaces, and you'd have to revise it too.)
One of the things that this tells me is that I should always try to start out writing tests, even if they are going to be enough of a pain that I will later abandon them. The test of my interfaces is worth it by itself, and it's a lot more real than writing example code or something.
(This isn't a novel insight, and it was sparked by one of the points made in Piers Cawley's Fluent Interfaces.)