Cook Computing


February 11, 2009 Written by Charles Cook

When I was at the last DeveloperDeveloperDeveloper day I came across usage of the word "spike" in software development for the first time. Extreme Programming has this definition:

Create spike solutions to figure out answers to tough technical or design problems. A spike solution is a very simple program to explore potential solutions. Build a system which only addresses the problem under examination and ignore all other concerns. Most spikes are not good enough to keep, so expect to throw it away. The goal is reducing the risk of a technical problem or increase the reliability of a user story's estimate.

When a technical difficulty threatens to hold up the system's development put a pair of developers on the problem for a week or two and reduce the potential risk.

I've noticed that when a developer has a technical problem they often try to solve it in-situ to the application they are working on. I prefer to write some completely standalone code to experiment with the problem so that I am not distracted by anything else relating to the application, such as building it or testing it. So I suppose I have intuitively been doing "spikes" for a long time.

Using spikes allowed you to isolate what you are experimenting with from your application code. This makes it much easier to share the problem with someone else. For example, a friend IM's you about a problem but you cannot check or run what she is doing because of she is not allowed you to send the application code, and even if she could you would have to install the app to run her code, whereas sending a small standalone project containing spike code presents no problems.

Another advantage of using spikes is that it separates test code from production code and makes it less likely that code of prototype quality is likely to end up on the trunk. Jeremy Miller's Don't Check In Spike Code… expands on this:

Don't Check in Spike Code…

...into the trunk.

Just like the title says, do NOT check "spike" code into the source control trunk. When you do an exploratory spike, you're generally throwing good coding practices completely out the window. You're on a focused mission to "figure out how this gosh durned thing is supposed to work." The code that you write in a spike probably sucks anyway.

Do spike whenever you're unsure how to work with some new library or technology or to try out a new object structure — but put that code in a branch. As soon as the spike has achieved its purpose, put that code aside, and write all new code in the trunk using TDD and your normal coding standards. You know, the coding and design standards that you've adopted as a team because you think those standards lead to sustainable quality. But Jeremy, I could just retrofit some unit tests around the spike code and call it good! Maybe, but you better ask yourself, am I really going to put decent tests around this code? Retrofitting unit tests never results in the same quality of tests as real test first development. Besides, as I said earlier, spike code generally sucks anyway;-)

I keep a large number of test projects containing my spikes as a reference for the various techniques, framework classes, and APIs I have experimented with. K Scott Allen responded to Jeremy's post with Spike Code and Source Control, where he describes the value of storing spike code:

Here are the kinds of things I've checked into "experiments/sallen" over the years:

  • Code to isolate and reproduce compiler, framework, and library bugs.
  • Code written to learn a new technology, platform, or library.
  • Code that I almost threw away because I was sure it would only be needed once (like a one time data import).
  • UI mockups
  • Code written to evaluate a product.
  • Code that doesn't work (because you'll have proof 6 months later when someone else has the same idea).

I've found that keeping a dedicated area for these types of check-ins offers some advantages:

  • It keeps spike code out of production branches (as Jeremy suggests).
  • It keeps code around that you might find useful to refer to one year from now.
  • After someone leaves a project, their experiments live on.
  • It saves you from saying "I think I tried something like that last year but threw the code away".

David Lambert describes how a spike can turn into what he calls a "reference architecture":

In other words, once you've used the spike to prove that something can work, you want to use it to show others how it's done. When that happens, you're starting to turn your spike into a reference architecture, and this is a much more important beast than your normal spike. Here are some signs that your spike might really be turning into a reference architecture:

  • It's documented. If you start to go through the trouble of explaining how this thing works, it's more than just a spike.
  • It's got more than one revision. If you check in updates to your spike to illustrate new ideas instead of building a new spike, you're growing a reference architecture.
  • It mimics the structure of your "real" application. If you go to the trouble of making your spike's project structure look substantially like your application's structure (or vice versa), there's a good chance you're going to end up with a reference architecture by the time you're done.

Code samples like this, particularly with some documentation, can be useful in explaining how to do something, often more so than a design document.

So, "spike" is a pretty obvious concept but with a little thought you can get a lot more value from it.