"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?
Also, referred to as a "steel thread". Runs the length of the application architecture (front-to-back, top-to-bottom, whatever) of what you are building. Each new top-to-bottom feature is a new thread. Steel threads wrapped together incrementally form a cable stronger than an equivalent diameter solid cable extruded all at once. Thread akin to string, as in string testing. - NormanECarpenter
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 ...
- Compounded complexity within existing code can distract from the essence of a requirement.
- Therefore, Write the smallest possible code that could be said to perform a function independent of existing mechanism.
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.
... 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
, 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.
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?
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.
' comments remind me of Fred Brooks' directive to "Write one to throw away", in MythicalManMonth
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.
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.
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
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.
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.
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%.
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
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
The first refactoring is to extract method on main to form a static init
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
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.
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.
Forgive me for asking, but I'm curious as to why there's a need for this term when the same process is already called research & development. Is there some aspect of a spike solution that traditional R&D does not cover?
I may have been using SpikeSolution
without intending to, but R&D depending on the level you are talking may start as a SpikeSolution
but will continue to grow. The point, as I understand it, of a SpikeSolution
is not to give you the full answer which, hopefully R&D will eventually lead to, but rather to give you a workable framework to determine how to make progress towards that solution. It is an initial step and when it moves onto something more it is that more and nolonger a SpikeSolution
. This is by no means a bad thing but one possible progression if you don't like writing throw away code. --AndrewRicketts
[often wrong but almost always opinionated correct if worng]