AoAD2 Practice: Spike Solutions

Book cover for “The Art of Agile Development, Second Edition.”

Second Edition cover

This is a pre-release excerpt of The Art of Agile Development, Second Edition, to be published by O’Reilly in 2021. Visit the Second Edition home page for information about the open development process, additional excerpts, and more.

Your feedback is appreciated! To share your thoughts, join the AoAD2 open review mailing list.

This excerpt is copyright 2007, 2020, 2021 by James Shore and Shane Warden. Although you are welcome to share this link, do not distribute or republish the content without James Shore’s express written permission.

Revised: July 18, 2021

Spike Solutions

Audience
Programmers

We perform small, isolated experiments to inform our decisions.

You’ve probably noticed how much Agile teams value concrete data over speculation. Whenever you’re faced with a question, don’t speculate about the answer—conduct an experiment! Figure out how you can use real data to make progress.

That’s what spike solutions are for, too. A spike solution, or spike, is a technical investigation. It’s a small experiment, in code, to research the answer to a problem. It usually takes less than a day. When you have the answer, the spike is discarded.

People often confuse spike solutions with walking skeletons: bare-bones code which demonstrates an idea from end-to-end. It’s the beginnings of a production implementation. In contrast, a spike is narrowly focused on a specific technical problem, and it’s thrown away afterward.

To truly understand a solution, write working code.

Spike solutions use code because nothing is more concrete. You can read as many books, tutorials, or online answers as you like, but to truly understand a solution, write working code. It’s important to work from a practical point of view, not just a theoretical one. The best way to do so depends on what you want to learn.

Quick Questions

For questions about your language, libraries, or tools, write a line or two of code. If your programming language has a REPL (an interactive programming prompt), that’s often the quickest way to get your answer. For example, if you wanted to know if JavaScript could use comparison operators on strings, you could open a web browser console:

> "a" < "b"
true
> "a" > "b"
false
> "a" === "a"
true

Alternatively, you can write a short test. You can put it right next to your real tests, then delete it afterwards. For example, if you wanted to know if Java throws an exception on arithmetic overflow, a throwaway test would answer the question:

@Test
public void deleteMe() {
  int a = Integer.MAX_VALUE + 1;  // test will fail if exception thrown
  System.out.println("No exception: a = " + a);
}

// Result of test run: "No exception: a = -2147483648"

Third-Party Dependencies

To learn how to use a third-party dependency, such as a library, framework, or service, create a small, standalone program to explore how the dependency works. Don’t bother writing production-grade code—just focus on demonstrating the core idea. Run from the command line, hardcode values, and ignore user input. Provide just enough design and abstraction to keep yourself from getting lost.

For complex dependencies, such as frameworks, I’ll often start with their tutorial. However, those tutorials tend to emphasize getting up and running quickly, not helping you understand the framework. They often have a lot of magic tooling that makes the framework harder to understand, not easier. So make their example your own. Remove magic, call APIs manually, and simplify unneeded complexity. Think about your use cases and demonstrate how they’ll work.

When you’re done, you can check the spike into your code repository to act as a reference while you build the real implementation. (I use a /spikes directory.) Once you’ve built out the production implementation, you can either delete the spike or keep it for future reference, depending on how useful it is.

Design Experiments

Ally
Reflective Design

If you have an idea for a design improvement, but you’re not sure how it will work out, you can spike the design. I’ll use this approach when I’m not sure if my design ideas will work as well as I think.

To spike a design, create a temporary, throwaway branch in your repository. In that temporary branch, you can experiment without having to worry about safe refactorings or passing tests. You don’t even need the code to work properly. The purpose of the spike is just to experiment with your design idea and see how it works in practice.

If your design idea doesn’t work out, delete the branch. If it does work out, you can keep it for reference, temporarily, but don’t merge it into your real code. Redo the change from scratch, this time taking care with your refactorings and updating tests as needed. When you’re done, delete the branch.

Allies
Incremental Design
Simple Design
Reflective Design

Avoid overusing design spikes. Although you’re welcome to create a design spike whenever it will help you understand your design options, they shouldn’t be necessary for every story. You should also be able to create new designs by starting with a simple, obvious approach that incrementally becomes more sophisticated, and you should be able to modify existing designs using reflective design.

Making Time for Spikes

Small, “quick question” spikes are usually performed on the spur of the moment. You see a need to clarify a small technical issue, you write and delete a quick spike, you move on.

Allies
Stories
Task Planning
Slack

Dependency and design spikes can happen in several ways. Sometimes, they’re planned intentionally, either with a spike story or a task. At other times, you won’t realize a story needs a spike until you’re in the middle of working on it. When that happens, you can either add a task to your planning board, or just work on the spike as part of your current task. Either way, your slack absorbs the cost.

Questions

What’s the difference between a prototype and a spike?

“Prototype” doesn’t have a strict definition, but it usually refers to incomplete or non-functioning software that’s made to mimic the final product. They’re often used to demonstrate UIs or to learn by building a throw-away version of the application.

Spikes are much more focused. They’re created to answer a narrow technical question, not to mimic the final product.

Should we pair or mob on spikes?

It’s up to you. Because spikes don’t need to be maintained, even teams with strict pair programming rules don’t require writing spikes in pairs.

One very effective way to pair or mob on a spike is to have one person research the technology while another codes. Another option is for people to work independently on separate approaches, each doing their own research and coding, then coming together to review progress and share ideas.

Should we really throw away our spikes?

Unless you think someone will refer to it later, toss it. Remember, the purpose of a spike solution is to give you the information and experience needed to solve a problem, not to produce the code that solves it. The real production code usually ends up being a better reference than the spike.

When should we create a spike?

Whenever it helps. Perform a spike whenever the constraints of writing production-grade code get in the way of figuring out a solution.

What if the spike reveals the problem is more difficult than we thought?

That’s good; now you have information you needed to know. Perhaps your on-site customers will reconsider the value of the story you’re working on, or perhaps you need to think of another way to accomplish your goal.

Prerequisites

Avoid the temptation to create useful or generic programs out of your spikes. Focus your work on answering a specific technical question, and stop working on the spike as soon as it answers that question. Similarly, there’s no need to create a spike when you already understand a technology well.

Ally
Test-Driven Development

Don’t use spikes as an excuse to avoid disciplined test-driven development and refactoring. Never copy spike code into production code. Even if the spike does exactly what you need, rewrite it using test-driven development so that it meets your production code standards.

Indicators

When you clarify technical questions with well-directed, isolated experiments:

  • Rather than speculating about how your program will work, you conduct an experiment that tells you.

  • The complexities of your production code doesn’t interfere with your experiments.

Alternatives and Experiments

Spike solutions are a learning technique based on performing small, concrete experiments. Some people perform these experiments in their production code, which increases the scope of possible error. If something doesn’t work as expected, is it because your understanding of the technology is wrong? Or is it due to an unseen interaction with the production code? Standalone spikes eliminate this uncertainty.

An alternative to spike solutions is to research problems by performing web searches, reading theory, and finding code snippets online. This can be good enough for small problems, but for bigger problems, the best way to really understand the technology is to get your hands dirty. Go ahead and start with code you find online, if you need to, but then simplify and adapt the example. Why does it work? What happens when you change default parameters? Use the spike to clarify your understanding.

Another alternative, specifically for learning how to use third-party dependencies, is to start by writing test code that exercises the dependency. As you learn how the dependency works, refactor your experiment into a “test” and “implementation” portion, then move the implementation into your production code. This approach starts off like a spike, but morphs into high-quality, tested production code. Episode 5 of [Shore 2020b] demonstrates the technique, starting at 13:50, and episode 17 has a larger example.

Share your feedback about this excerpt on the AoAD2 mailing list! Sign up here.

For more excerpts from the book, or to get a copy of the Early Release, see the Second Edition home page.

If you liked this entry, check out my best writing and presentations, and consider subscribing to updates by email or RSS.