Spike Driven Design

October 20, 2012 Jonathan Berger

I’m really excited about a collection of new techniques I’ve been experimenting with over the past few weeks. They’re an evolution of the in-browser design approaches I’ve been using for the past few years, and taken together they help my team build better designs with less waste in a tactic I’ve taken to calling Spike Driven Design.

UPDATE: This is a blog-post version of the talk I gave last week at the Agile Experience Design / NYC SASS & Compass co-meetup. You can find the slides on my Talks page.

The Problem:

Traditional, Adobe-app-based design is great for designing before any software is built, for quickly iterating on user flows, and for experimenting with new high-level concepts. On the other hand, it suffers a heavy tax once working software exists and mockups have to play catchup with reality, and it does little to aid in designing interactions (Fireworks and Flash have an advantage over Photoshop and Illustrator in this regard, though they’re far from ideal).

Designing in the browser is great for working out low-level tactics, quickly iterating on interface and small interactions, and suffers almost zero set-up cost: install Firebug or tick the “Show the Develop menu” box in Safari’s prefs (or just install Chrome!) and you’re good to go. On the other hand, the toolset and techniques are immature, there’s a reasonably high learning curve, and the tools are tantalizingly close to the real app, but not quite there. Saving your work is difficult (to say nothing of iterating over a few ideas), and replacing text by hunting and pecking into Firebug fields gets old fast. For quick-and-dirty mocks, some light Firebug hacking, a screenshot, and a trip to Photoshop may suffice, but this workflow doesn’t hold up for prolonged investigations into a new user flow or feature track.

Enter Spike Driven Design. Rather than design in an Adobe app or even in the browser, I’ve taken to designing in Rails itself, using mostly SASS and HAML and little bits of Ruby. Whereas designing in the browser helped fake the front-end for mockups, it could never help with data. Now I can fake the back-end too! I’m not bothering with tests, and like any true Spike (in the Agile sense), this is code that is written to be thrown away. That gives me the freedom to move fast, focus on the UX and visual design problems without worrying about much else, and design using the actual medium the user will end up with: working software.

What’s a spike?

Plenty of ink has been spilled on the topic, but at heart, an Agile “spike” is a short investigation into a technique or a problem. For instance, when it comes time to build our Recommendations feature into my sample e-commerce site Hamazon, we might put a time-boxed chore into the backlog: “spike on recommendation algorithms and choose one”. By nature it’s explicitly exploratory and limited, and the goal is learning (rather than working software, the sine non qua of Agile development). After a spike is completed, the code must be thrown away. This is important: the imperatives to learn fast and to write healthy code are necessarily opposed, and the temptation to keep the code is always present. Resist it. Chuck the code. Now that you know the approach you want to take, write it again and write it right.

What’s SDD?

To start Spike Driving your design, branch the project, and begin to gleefully and recklessly hack around. For instance, if I were SDD’ing a new Order History feature for Hamazon, I’d want to have a bunch of orders to play with in my design. Instead of mucking around with a database and orders, I might just write a method called “orders” that returned a pre-canned list.

def order_history
        [
            {order_id: 102173, order_date: "8/1/2012", price_in_cents: 1799, item_name: "Snout T-Shirt", item_id: 1  },
            {order_id: 102384, order_date: "8/1/2012", price_in_cents: 3699, item_name: "Berkshire Ham", item_id: 2  },
            {order_id: 102930, order_date: "9/1/2012", price_in_cents: 1599, item_name: "Piggy Mug", item_id: 3  },
            {order_id: 103151, order_date: "9/14/2012", price_in_cents: 3699, item_name: "Berkshire Ham", item  _id: 2  }
            {order_id: 103944, order_date: "9/15/2012", price_in_cents: 2299, item_name: "Tactical Bacon", item _id: 6  }
        ]
end

Obviously this doesn’t get us closer to anything that helps a user, but it lets me start designing with real(ish) data, real quick. I’ll call #order_history in a view somewhere, get the list of orders on the page, and start marking up and styling them. I also might put a comment at the top of this message: # TODO: make this real. It’s kind of a shady move to push all the real work onto “someone will take care of this later”, but running a quick grep todo lets us see all real dev work that needs to be done.

While I’m playing around in the Orders History page, I notice that the navigation is going to need a link to the Order History for the User Flow to make any sense, so I’ll throw that in now. (An aside: it may be a little premature to commit any of this to git, but when you do start checking in your work, take care to keep your commits small and atomic.)

Ugh, now that we need secondary navigation, that bloated 60px header bar really needs to be trimmed down.

Let’s deal with that right now, hop into the appropriate stylesheet, and bring it down to 30px. As I work, I’ll play around with the interaction, navigating through a normal user flow, jumping into the Order History, and then back.

Hm, these order line items are starting to look ok, but they could use something a little more visual; how about some icons? Which, now that I look at it, should really light up on hover, so let’s create some assets. Oh, also, we’re probably going to want to be able to perform bulk actions on this list.

I don’t need to write a working form, I can just throw in the checkboxes and select lists in the appropriate places—they don’t have to be wired up to anything. Ok, this looks pretty good; the PM (who sits right next to me, and has been chiming in along the way) and I pull a dev over to run through this with him and make sure nothing sounds too crazy. Once we’ve got the rough ‘ok’ we can start writing well-formed stories in Tracker and take screenshots of the SDD site and attach them as mock ups. I’ll also create an epic called “SDD-order_history”, and attach a note mentioning where the branch lives and what I’ve done in it.

So that’s the rough version of Phase One. Now the fun begins. If I haven’t done so already, I’ll go back through my work in git add -p or GitX and break all my changes down into small, atomic commits. Generally, I’ll have a few kinds of commits:

  • Changes that require functional code and tests, and
  • Styling changes that can go right into the app.

Now I hop onto the master branch and start cherry-picking those styling commits: BOOM! Free style tweaks and polish! All the design fit-and-finish that I meant to write stories for and get to at some point are now done and in production.

Phase Two is when the devs get to the SDD’d stories in the backlog (which ideally is within a few days). There’s a comment pointing them to the branch, which they can check out as a renamed repo and then run on another port:

git clone git@github.com:jonathanpberger/hamazon.git hamazon-sdd-order_history
cd hamazon-sdd-order_history
... (bundle, set up db's, etc)
rails server -p5555

During development they’ll run the real app on port 3000 and do everything normally, but living, functional mock-ups exist for reference on port 5555. Furthermore, they can take a look at the code for ideas on things like structuring the DOM, and can even harvest things like SASS and assets from the branch. This means that a lot of the work from the design phase can go directly into the finished project, without duplication of effort, and without sacrificing quality.

When / Where?

So what sorts of projects and teams are good candidates for SDD? On this project, we’ve established the basic design of the app and have a while to go before we’ll need to do the Big Design Refactor. We’re building a fair number of small or medium-sized features or feature tracks, and it’s important that we make sure our additions work well within the existing app and user flows. We’ve got two pairs of developers (one of whom is off-site), plus me (a design-developer hybrid). Naturally, the designer employing SDD needs to be fairly technically literate. Another nice side effect of SDD is that the team is almost never odd. SDD stories pull me into the pair rotation in a non-time-sensitive manner, which helps smooth out rough spots in the rotation if someone has a doctors appointment or is interviewing a candidate. All of which to say, SDD seems to work well on projects that’re past their initial design phase, and have small- to medium-sized teams with a technical designer.

Problems w/ SDD

So what problems exist? Because of the technical requirements, there’s a high learning curve for the designer. It feels a little risky (shady even?) to push real work into comments saying “make this real”. There’s a potential for non-production quality code to leak in when. The SDD branch tends to get stale quickly. If you try to go back to it two weeks later the main line will have moved on, and these merge conflicts tend to be especially thorny because they’re usually very similar to changes you since will have made.

Despite these shortcomings, SDD has proven to be an effective technique for our team. We look forward to continuing to explore this way of working, and especially to hearing if it works for others.

About the Author

Biography

Previous
Hunting Memory Leaks in Backbone
Hunting Memory Leaks in Backbone

Ever notice your backbone app slows down considerably after using it for a few minutes? Or maybe your even...

Next
Custom Transforms in Ember Data Rev 6
Custom Transforms in Ember Data Rev 6

Ember Data is a library for loading models from a persistence layer (such as a JSON API), updating those mo...