Ramblings on the design phase

[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.

#1 Darrell on 12.10.2003 at 5:46 AM

Hey Steve, I posted a response to your post, showing some quantitative data to support doing some design and not trying to "refactor your way" to it.Check it out at dotnetjunkies.com/.../4361.aspx

#2 Wayne Allen on 12.12.2003 at 12:22 PM

A collegue of mine (Jim Shore) would argue mightly with you about refactoring "hard" features into a system. Check out his article in Jan/Feb IEEE Software.

#3 Udi Dahan on 12.15.2003 at 5:25 AM

I think that you omitted a critical element of the XP/Agile process that takes care of some of the issues raised. This element is the "System Metaphor". The system metaphor often includes architecture related issues that are indeed agreed upon up front. Notice, however, that this is at a level above design. In an SOA world, this would include the basic services that make up the system. In a recent post I pondered the SOA/Agile mix - http://udidahan.weblogs.us/archives/005125.html. Now, for the most part, the system metaphor stays stable during the life of the project, however, "code is king" drives the evolution of the metaphor as needed. When talking about design though, you CAN refactor your way to a good-enough design.The main thing when developing systems, and especially large ones, is to use complementary approaches. Use prototypes to quickly flesh out requirements in central use cases ( take a look at my post at udidahan.weblogs.us/.../005373.html ). Use "tracer bullet" development ( a la pragmatic programmers - pragmaticprogrammer.com/.../1999_03.html ) for architecturally important requirements - think something along the line of the system skeleton on which the rest of it will hang. Use whatever fits, that's what agile really means.On the issue of specs, in an SOA view, it IS important to agree upon the contracts between services. You can usually get 80% completion pretty quick. As development progresses, the contracts will also change, but the changes will come at a relatively slow pace due to the fact that the System Metaphor is stable.