[Update: Darrell Norton has some really good metrics about agile development and design over at http://dotnetjunkies.com/weblog/darrell.norton/posts/4361.aspx]
Right now, I’m deep in my favorite part of the software development lifecycle. For me, the design phase is the most stimulating part of a project, and certainly the most fun. It’s where the general problem gets defined, the core architecture gets laid out, and most of the “interesting” problems get solved. At this point in the project, we’re free. The possibilities are constrained only by our own ingenuity – it’s very empowering.
The presence (or lack thereof) of an explicit “design” phase in Extreme Programming is something that always seems to come up in discussions of XP and other agile methods. The XP mantra of “the source code is the design” is often misconstrued by XP naysayers to mean that there is no place for design activities in the world of Extreme Programming. I don’t think this is at all the case. I would venture to say that good software cannot simply be refactored into existence; there must always be some vision driving the implementation, and that vision will always exist regardless of the methodology being used on the project. Agile software methods just have a different approach to the design phase than more formalized methodologies.
In BigDesignUpFront methodologies, the outcome of the design phase is an exhaustively detailed technical specification that solves every problem that will ever occur during the course of implementation. Of course, as we all know, such specs are virtually impossible to write. They also don’t drive immediate value because they’re really nothing more than a big stack of paper. In XP, I think the output of the design phase (like just about every other deliverable in XP) should be a prototype implementation -- some small instance of a general problem that you can build independently in a few hours and get immediately passing unit tests. Prototypes and proofs-of-concepts are great because they’re small enough to be manageable and yet big enough to provide a general assurance that the proposed approach will actually be feasible. On large or highly complex projects, I think it’s worth investing a couple days to do prototype to avoid having to do a drastic mid-course correction down the road.
But aren’t mid-course corrections what agile methods are all about? Can’t we just dive right in and “refactor our way to glory”? I think the answer is yes – to a degree. Refactoring gives you wiggle room in a design and allows you to avoid having to lock down messy implementation details up front. It does not give you total freedom to easily change your approach to the problem halfway through development. Refactorings are code transformations that preserve the semantics of the orginal code. If you can’t get to where you need to be by keeping the original “spirit” of the solution, you’re out of luck. I don’t think refactoring will help much in that case.
We’re taking the time in my current project to do some prototyping early. Instead of writing extensive tech specs, we’re writing code to prove out our ideas. As a result, we’ve learned some fairly interesting things about our problem domain that would not have manifested themselves until our project had grown to the point where working around those oddities would be prohibitively expensive. Even though it’s pretty likely that none of this prototype code will make it verbatim into the final product, I still think it’s been a very good use of our time.
