How do you design? Do you sketch static and dynamic diagrams in UML? Do you use CRC cards? Or, do you just sit with your team each day and reach a verbal consensus on design issues before breaking to code? In my career, I’ve used all of these approaches; I’ve been on teams that vary wildly in the level of formality that they use during design, and I’ve noticed that there is little correlation between that formality and the quality of the resulting designs. At times, there even appears to be an inverse correlation.
At OOPSLA 97, I was lucky enough to walk into a “birds of a feather” session hosted by Kent Beck and Ward Cunningham. They were talking about pair programming, but what they were doing was even more startling. : They were coding, in place, the heart of an accounting system in Smalltalk and showing how it could be evolved to accommodate just about any use we could throw at it. Afterwards, I was a little stunned. After all, we all know that you can’t just start writing code and end up with something well structured. Design is hard work, and coding is much too costly.
Over the next several years, I used many of the practices that became part of extreme programming and I tried to dig in deeper to understand how good design can emerge from a set of local decisions. I tried something that Kent Beck had been practicing, evolving a design from a single object. : In XP, we often recommend some exploration before coding, system metaphor work, but I decided that it would be good to investigate the worst case. What happens when you design as if you really have no idea what the next requirement will be? Can you evolve your code in a good way? After all, if you can work well with the worst-case, imagine how much more confident you can be when unexpected requirements put you there. What I discovered by placing myself in this awkward position has completely changed the way I see and develop software. The running examples on these pages document what I go through in the act of design. I hope you enjoy them.