As you know, I’ve always tended toward the “lean” school of agile software development, even though sometimes I’ve found parts of the mapping difficult to envisage. One area I never understood clearly until recently is set-based or concurrent design, in which competing potential solutions to a problem are developed in parallel until it is absolutely necessary to decide among them. Why and when would it make sense to do such a thing during software development?
My initial answer to that question was “YAGNI”. By having code only for the requirements we have scheduled (and which are therefore definitely needed), we leave the product in a better state to respond to whatever comes next. If we have persued YAGNI thoroughly, our current codebase represents the intersection of all possible decisions in the future; we might therefore be said to have developed all of these possible futures in parallel upto the present moment.
Which is probably valid, but unconvincing. Then a recent thread on one of the lean/agile lists had me thinking about the problem again. In discussing motor car design – specifically the Toyota Prius – Mary Poppendieck said:
“I think that the trick is to determine what is, in fact, easy to change later, and what will not be easy to change, and spend some time considering those things that are going to be very expensive to change later. And, of course, the trick is also to keep such things to a minimum – through the use of layers, services, etc.”
Then I understood. I’m currently just starting up a new project to develop an application to help with my business. Before writing any code and before writing any stories, I thought about what existing process(es) will be helped / enhanced / automated by this new software, and therefore how it needs to be accessed. I decided that I want to access the software from a browser, for various reasons. And I expect that decision will be relatively cheap to change later, so I make the decision quickly and move on.
But then I have to decide what technology to use in implementing the thing. Should I use Java, which I know very well, or is this a chance to try Rails? Either way, this will be a very hard decision to reverse, so I need to make it carefully. I need to know that this concrete decision will be made right before I invest any long-term effort in the project. Consequently, I’m currently in the middle of a fairly large spike exploring what Rails has to offer. This is concurrent engineering (even though it’s proceeding serially due to the fact that there’s only one of me). I know that “architecture” can be a dirty word in some places, but that’s what I’m doing right now: making those few decisions that will cost the most to change later. I’m exploring the options by producing product-quality software, and I will soon arrive at the point when I am forced to choose. This will be Mary’s “last responsible moment”. The decision will be made in the light of concrete evidence, and at that point either Java or Rails will be discarded in favour of the other.
So that’s now my answer to the question I posed above: Spikes are the agile equivalent of Toyota’s set-based design. Make all decisions as late as possible, and make them based on evidence from concrete experiments. In my case I do have to choose a development language & tools, and the decision will be costly to reverse. So I create spikes to help me decide, because the cost of being wrong is greater than the cost of the spike.
Bill Wake mentions both of the above interpretations in this article.