Spreading out Design

Even before my first experience with full-on eXtreme Programming (XP), I was mulling the problem of how much design to do when. I’ve seen too many waterfallish projects either throw away much of their early design work, or go chaotic late in the schedule trying to cling to an early design in the face of a new reality that needs something different. When defending waterfall, it’s almost cliche to trot out some variation on Eisenhower’s famous saying, “In preparing for battle I have always found that plans are useless, but planning is indispensable.” I used to nod sagely, but now I see it as a poor excuse for the amount of waste that happens when you try to do the bulk of your design work up front.

XP seems to cure waste by spreading out design over the course of the project, doing only enough to satisfy the work at hand, followed by aggressive refactoring. Working on an XP project, I found, to my pleasant surprise, that this “small steps” approach worked very, very well. Doing small bursts of design, writing tests first, coding up the simplest implementation that would satisfy those tests, and then stopping to clean house by refactoring, proved to be an highly effective way to develop. Except when it didn’t.

Working a story (use case) at a time keeps us focused. Having a large body of tests gives us confidence that we aren’t screwing something else up (and nudges us towards writing testable code). Pairing helps spread domain and technical knowledge around. Refactoring keeps the code base clean. But this isn’t always enough to prevent design debt from building up.

There are points in the evolution of some systems where something happens that changes the game. It may be the introduction of a new requirement, such as “now make it work on the web”, “support simultaneous edits”, or “accept foreign currency”. Or it may happen when increased demand forces our system to expand beyond a single server. However it happens, the game has changed in some fundamental way, and the code base we have, or some significant part of it, isn’t structured in way that fully supports the direction we now find ourselves headed. We could try continuing to move ahead in small steps, but some of those steps get harder and harder to take. It’s time to invest a larger chunk of time in design, with the intent of getting ourselves back on the “small incremental design” track.

So plan to spread out your design, but don’t expect to spread it smoothly like peanut butter. Expect some big chunks.

On a slightly related note, this video interview with Ron Jeffries is excellent. It’s mostly about dealing with fixed dates and the importance of testing, but he makes some points about spreading out design, and not expecting it to spread evenly, that might be helpful if you find yourself in setting expectations about using Agile.

Team sizes that maximize pairing

Let’s say that you’re a manager who is convinced that pair programming is a good thing, and that you’re growing an existing small team or staffing a new one. How many developers do you add to the team to maximize pairing? (Let’s assume that the developers are all pairing-positive. Maximizing pairing when the team isn’t entirely pairing friendly is a question for another day. We’ll also duck the question of when a team gets too large.)

A team of one is a non-starter, even if the sole team member mummbles to himself while working.

A team of two works.

A team of three doesn’t work. At least one person will be solo at any given time. You’re better off skipping three and going right to four.

The obvious answer is to keep the team an even size.

But people take vacations. And sometimes get sick, or have car problems. Or a tree limb falls on a house. Or there’s an inconveniently timed meeting at school with a kid’s teacher. Life happens.

The larger a team gets, the greater the chance that at least one person will be out at any given time. At some scale, the obvious answer of maximizing pairing by keeping the team an even size breaks down. The “50% chance of exactly one absense” points depends a lot on context (team mix, vacation policies, local weather patterns).

A quick after-the-fact, back-of-the-envelope calculation for an XP team I worked with a while back suggests that after six developers, moving to seven, and then nine, would maximize pairing opportunities. At least for that team, in those circumstances. Your context, and hence your numbers, may vary.

If you are growing an existing team that practices pair programming, count the number of days that one developer is working solo because a pairing partner isn’t available. If it’s more than half of working days, (and all other things being equal, which they never are, so of course you’re going to consider other factors), lean toward adding one developer. Otherwise, you might consider holding off on growing the team until you have budget for adding two developers.