Spike Solution

"Spike" because TopDown is typically BreadthFirst, but a Spike is DepthFirst. From the top to the bottom, then CloseTheLoop.

So-called because a spike is "end to end, but very thin", like driving a spike all the way through a log.

Now described in Alistair's medical format in SpikeDescribed.

YagNi + domain_ignorance?


I would often ask Kent, "What is the simplest thing we can program that will convince us we are on the right track?" Such stepping outside the difficulties at hand often led us to simpler and more compelling solutions. Kent dubbed this a Spike. I found the practice particularly useful while maintaining large frameworks.

I've mentioned that it is to be a part of Episodes-II when ever that gets written. The following pattern is from my overhead slide of the same name ...

RonJeffries tells me that he has an elaboration of this in the works too. There, now we are both on the hook. -- WardCunningham

A micro example of this occurred at OOPSLA 97 at Ward's and my PairProgramming BoF. Someone asked us to implement accounts and transactions in less than five minutes. Here is the code for our first spike:

  #(10 -5 -2) inject: 0 into: [:s :e | s + e]
The final balance of this account is, of course, 3. Our user then added the requirement that the transactions be dated. The new spike looked like this:
  t := #((10 0) (-5 3) (-2 7)).
  (t select: [:e | e last < 5]) inject: 0 into: [:s :e | s + e first]

The point with this spike is that we were able to explore (learn about) the crux of the problem- the combination of selection and summing- without invoking any of the impedimenta of objects.

Spikes are good when you are knowledge-limited, not time-limited. -- KentBeck

... and I am really sorry I did not see SpikeSolution in time to ask you for a copy to put into the appendix of my book with the other knowledge-based ProjectManagementPatterns. It is a perfect complement to ClearTheFog, EarlyAndRegularDelivery?, ProtoType?, and MicroCosm, illustrating something none of those do. SpikeSolution is a cross between EarlyAndRegularDelivery? (deliver increments continuously to get feedback on the process) and ProtoType? (codify subset of best current understanding to shed light on the problem or solution), and much shorter in duration than anything I suggested. I cite SpikeSolution to many people these days as the shortest initial 'V' in a VwStaging? policy (where a V is either a prototype or a deliverable increment).

On the Chrysler C3 project, the way we use SpikeSolution, in the context of Alistair's patterns, is as a tiny version of ClearTheFog. We like a SpikeSolution to take no more than a couple of days, and a half day is ideal. We plan to throw away the code, although sometimes something is salvaged.

Sometimes we might use a Spike to learn about the algorithm, as with the accounts example Kent gives above. Those should take minutes in most cases, not hours.

Usually, however, we'll go deeper, using the real objects, and broader, typically from reading the real input to writing the real output. We found that when we didn't consider the full breadth, we got into trouble, so we changed our process accordingly. -- RonJeffries

One more thing ... there's a special kind of discovery that goes with the kind of SpikeSolution Kent shows above. This approach goes to the core algorithm, and shows you the shape that the final solution would like to have. Here we see that we'd like the collection of accounts to have real Collection behavior, selection and injection.

When we focus on this "inner loop", it seems to me that we are exploring some essential reality of the problem and its natural solution. We can focus the outer parts of the solution (the input and the output, for example) to bring us the objects that are just right for making the core algorithm clear, simple, and efficient.

This sounds weird and vague even to me, but I know there's an idea in here somewhere. Fix it for me? -- RonJeffries

If I said "transform-centered design", would you hit me? What I hear you saying is "Write the middle first". After you understand the middle, you know the preconditions and postconditions necessary to support it. -- BetsyHanesPerry

RonJeffries' comments remind me of Fred Brooks' directive to "Write one to throw away", in MythicalManMonth. -- KatyMulvey

Don't look broke to me. It does remind me of DijkstraAndRefrigerators. ps. I just took a crack at describing it in my medical pattern form in SpikeDescribed. -- AlistairCockburn

Perhaps not broke, but the essence of "write one to throw away", to me, is that you learn something from your first attempt to write something. This pattern says the same thing, with the constraint that you keep your first attempt small and simple, so you can learn something new quickly. -- KatyMulvey

This reminds me of a standard technique for learning a new programming language (see HelloWorld) or testing the actual effect of some command or language construct.

Create the shortest possible procedure (or object and method) that exercises the command (containing only command, output, and life-support). Compile, run (possibly in the debugger), and modify until understanding comes.

Although this should be obvious, sometimes I forget and instead wade through huge chunks of code in the debugger. -- WayneCarson

If we regard a SpikeSolution as research, there's a quote from RogerNeedham on the lines of The best research is done with a shovel, not tweezers

-- SteveFreeman

I've put my experience with SpikeSolution(s) on the ATS project in AtsSpikeSolution. -- JimLittle

I hope XP authors will write SpikeSolution uses into future XP books. I have had a very enlightening experience with a SpikeSolution. My experience and recommendations are at SpikeAsDesignAid. -- BretWilliams?

Is a SpikeSolution the same thing as TracerBullets, described in ThePragmaticProgrammer? -- Paul

We choose to write this code first, not because it is easy, but because it is hard. -- JohnFitzgeraldKennedy?

These remind me an awful lot of the famous APL one-liners (1970 vintage), where each operator did the work of many lines of traditional code. Often the whole program consisted of a single-line, especially in the hands of a master, like Ken Iverson and Adin Falkoff. -- Birol AygŁn

APL: Try the K or J programming languages.

An ExtremeProgramming variation I am experimenting with is to develop spike solutions in the style of unit tests so they are integrated into the build system and, hence, the totality of the extreme programming experience so that all programmers have the potential to benefit from availability of further research on spikes, so that if fundamental project foundations change (core vendor libraries external to ones user stories) the spikes actually break at the right time so someone catches it and refactors the spike if there is a payoff...or one just deletes it.

This seems to be working so far except the spikes are noisy and occasionally interfere with a quick run of all tests.

I guess I am so TestInfected at this point that I cannot explore any programming task, including spike solutions, without first writing a UnitTest. And since XP believes the fastest way to deliver deliverables is by doing XP, then a spike solution, since it is a deliverable, ought to be done with miniature XP iterations. And that includes stories, tasks & estimates, unit tests, and an ExtremeProgrammingEndZoneDance? when all tests once-again pass 100%.

-- EricNewhuis

A common idiom in writing small Java programs that make heavy use of one or more libraries is to write a static program. This will commonly take place as part of a spike in an XP project to examine how external class libraries are used. However, after some amount of time, the program needs to become a full-fledged object. Unfortunately, such a program will probably use "tester inspects output" as the testing regime. In this context, all but the main method will be private, as nothing calls this program, and it isn't subclasssed. What series of refactorings is needed to change a static program into an object?

The first refactoring is to extract method on main to form a static init method. This refactoring will create a method that will have a String[] argument to accept the command line arguments of main. At this point, a simple unit test can be written by making one or more of the static fields public, and writing corresponding test methods to test the values of these fields after calling Class.main().

Next, create a constructor that calls init. This constructor should take a String[] argument. This argument may be removed later or other constructors added. A unit test can now be added that calls the constructor, then accesses the static fields in much the same way as the previous unit tests.

The next step is the biggest. Change all of the appropriate static fields to instance fields. Change all of the appropriate static methods to instance methods. This will include the init. Change main to call the constructor instead of init. The unit tests will now need to be changed to reference the fields as instance fields of the object, rather than as static fields of the class.

At this point, do encapsulate field on the appropriate fields. Rewrite unit tests to use the field accessors, rather than directly accessing the fields.

If the program does more than one calculation and clients of the class may not need all of the different calculations, then make the appropriate methods public and move code from init into these methods. Write unit tests for each of these public methods.

This is somewhat like make data objects, but has to deal with behavioral aspects.

Can showing this (series of) refactoring(s) help students learn proper OOP techniques? By taking a program that properly follows structured programming using an object-oriented language, would this help students understand how to properly encapsulate, distinguish class from instance data, distinguish class from instance behavior, how to introduce unit testing where none existed before, etc.

-- JoelJones

I did this on another project (didn't know it was XP), and I thought of it more as being like building a suspension bridge. First, you get the string over the chasm, then you use the string to pull a light rope across, the light rope to pul a heavier rope, and so on, The key is to get that string over, all the way, from one side to the other. On this particular project, the chasm was the public InterNet and the string was an SSL connection.

EditText of this page (last edited February 28, 2006)
FindPage by browsing or searching

This page mirrored in ExtremeProgrammingRoadmap as of April 29, 2006