Design-first development

The first RubyConf talk I gave was entitled Cleanliness Is Next to Domain-Specificity; in it, I spoke about DSLs, and gave an example of how you might want to create one (I also spent some time talking about regional variation in Little Bunny Foo Foo, but that's neither here nor there). At the time, I said that the best way to design a DSL was to write out what you wanted it to look like, and then write the code that made that functional. I've since become convinced that this process is in fact the best way to design any code, not just DSLs. API? Write out how you want to call it, then write the code that responds to those calls. Routing in a web app? Write out the URLs you want people to hit, then create the code and routes that will make those work. A web page? Design the page, build it out into HTML, and then write the code that makes it live. Each of these is an example of design-first development. You may be wondering if I'm abandoning the lean/agile fold for waterfall with this idea. Happily, I'm not. If you think about it, this is how TDD (or BDD) works: you write a test or spec that runs some code (in the process, designing how you'll interact with the code), and then you write the code that makes it pass. The sort of design I'm talking out isn't fossilized in spec documents, but is actually executable when you finish writing the code to make it work. The key to all of this is realizing that design happens at a number of different levels. In the examples above, I described design the level of writing code (DSL), of integrating with systems (API), of browser interaction (routing), and of user interface (web page). I think that more and more people are realizing the power of this approach at various levels, but I'm convinced that recognizing each of those levels as an instance of using design-first development may provide better insights into the process overall.