Note: This is a guest post by Lasse Koskela originally published on his late blog. Thanks to Lasse for letting me re-post it here.
I’m sitting in the hallway in Limerick, Ireland, attending the XP2008 conference, downloading something from the company server to my laptop, eavesdropping on an open space session hosted by J.B.. He’s talking about user stories and roughly 4 minutes ago he mentioned he’s got a blog post up on his website that shows an example of four ways to split a story.
Since I’m so Web 2.0, I’m blogging about this while they’re having their open space session two meters from where I’m sitting. I tried to be Web 2.0 and blog this while they were running their open space session but I’m so darn slow and old school that it took me 2 days to get this written! Hardly enough to blog about it as it happens. I should’ve recorded a podcast, I guess.
I’ll first reproduce Joe’s list of four ways to split:
- splitting stories along process lines
- splitting stories along architectural lines
- splitting stories along procedural lines
- splitting stories into smaller stories
What Joe is saying in his blog post (among other things) is that teams often progress through this list, starting from the worse way to split down stories and (hopefully) ending up with splitting stories smaller so that they’re still “self-contained increments of value.”
Great. I’ve seen this pattern.
Now, having seen this pattern and having found that people find it difficult to split in any other way than what they’ve done so far unless they can look at examples, I thought I should share what I teach about splitting user stories.
Let’s start with my list of ways to split user stories (not in any specific order):
- by implementation (Joe’s first two bullets)
- by quality
- by data/details
- by operations (CRUD)
- by major effort
- by role
Let me explain what I mean by these, along with an example of each.
Splitting by implementation
First of all, this should be your last option. It’s very intuitive for an engineer but you should only do this if you honestly can’t think of another way to split it down. Only then you should consider looking at the technical tasks you need to carry out in order to make the original story come to life in the software or split along the lines of architectural boundaries, components, or another technical boundary.
Once you’re done splitting it down like this, you call your mother to apologize, check Google Maps for the shortest route to a nearby Catholic church for a confession during the lunch hour, and pick up a new brush from Walmart on your way home. You’ll need the brush while sitting in the corner of your shower, scrubbing your back violently, chanting “I feel dirty.” That’s how bad way this is to split stories.
Now for the example I promised. Let’s imagine we’re building an online retail system like Amazon.com and we’ve got a user story like this:
As a potential buyer I want to see available multi-item discounts involving the product I’m currently looking at.
If this is too big for us, how could we split it further by implementation? We could, for example, split into two stories – the original and a smaller story that’s a dependency for the original:
As a product owner I want the discount subsystem to support multi-item campaigns so that I can deliver value to the user in a later iteration.
See? With this split down story we’re not delivering any value to the end user because it’s a technical split. To emphasize this, I’ve expressed the story in a form that makes it explicit that we’re doing this in order to enable a later value-delivering story.
Now that we’re over the evil implementation split, let’s look at some more useful ways to split stories.
Splitting by quality
When I think about the goodness of a user interface, I divide the question into two: utility and usability. Utility is about whether the user can achieve the goals he has with the system. Usability is about how easy it is for the user to reach that goal. This dual model can help us split down user stories because the two aspects – utility and usability – can be valuable as such and have different priorities.
Let’s look at an example from an online store selling photography equipment:
As a beginning photographer I want to get recommended a camera kit to buy so that I don’t need to spend hours reading reviews to figure out which camera would suit me well.
Now how would we split this story along the lines of quality, separating the concerns of usability from pure utility?
Well, the utility aspect – the goal – is for the user to be able to figure out which camera to buy. This would be a lot easier if the system could make a smart recommendation. That recommendation might, however, be too difficult to implement right now, making the story too big. With that said, we can support the user’s goal (utility) with less quality (usability) through, for example, a split to these two smaller user stories:
As a beginning photographer I want to see a numeric sales rank so that I can better decide which camera to buy by comparing the sales of my alternatives.
As a beginning photographer I want to see a numeric sales rank grouped by buyer expertise level so that I can better decide which camera to buy by comparing the sales of my alternatives.
These two stories aren’t quite as valuable to the user as getting a clear recommendation but they are valuable in that they help the user make that buying decision. They’re the cobblestone road solution that’s not quite the asphalt highway we’d eventually want but it’s already better than no road at all or a bumpy dirt road.
Splitting by data/details
One of the easy ways to split down user stories is by data and details. The classic example is searching:
As a user looking for camera accessories I want to search for products so that I can avoid browsing through the whole product catalog.
Now, let’s say that it’s too much work for us to implement the search facility in all of the function and polish we’d eventually like to have. We can, however, implement a subset of that fully-featured search by splitting along the kinds of data and details we support. For example:
As a user looking for camera accessories I want to search for products by their name and description so that I can avoid browsing through the whole product catalog.
As a user looking for camera accessories I want to search for products by their price and availability so that I can avoid browsing through items I wouldn’t buy anyway.
In other words, we might first implement a search that only looks for matches in the name and description of a product. In the next iteration, we might follow up with extending the search to other data fields such as price and availability.
In some cases the difference between supporting 2 or 4 data fields can be negligible and therefore splitting along these lines might not make much sense. However, it could be that the type of data in question makes that difference significant enough that splitting actually does produce multiple significantly smaller stories than the original. In our example above, we’re not really going to match the exact price but rather a price range. Similarly, we might want to search for availability in a specific location rather than a simple “yes, we have it” match.
Splitting by operations
Another intuitive way to split down user stories is along the lines of operations and procedures. An archetypal example of this could be a CRUD (create-read-update-delete) scenario of managing products in a database:
As a shop keeper I want to manage the products being sold in my online store so that I can sell what people want to buy.
If this is too big for us, we might split along the lines of the CRUD operations like this:
As a shop keeper I want to add and remove products from my online store so that I can sell what people want to buy.
As a shop keeper I want to edit product details in my online store so that I can avoid recreating a product to fix a typo etc.
These are both valuable stories. We could just implement the first story and, for now, deal with updating product details by removing and recreating the same product in the system with the new details. We could just implement the latter story and accept that we need to add new products into the system with raw SQL.
Usable? No. Doable? Yes. Acceptable? Depends.
Splitting by major effort
Yet another way to split down too big user stories is by identifying where the effort would go. Let’s use the classic credit card example:
As a buyer I want to be able to pay with a VISA, Mastercard, Diners Club, or American Express credit card.
Now, our first thought might be to split along the lines of data and details – the different credit cards we support – but that would give us four user stories (one for each card type) with identical, conditional effort estimates. Why? Because implementing support for any one card takes at least as long as adding support for all the rest. Recognizing that this is how the effort is divided, we might split the above story into these two smaller user stories:
As a buyer I want to be able to pay with a credit card (one of VISA, Mastercard, Diners Club, American Express).
As a buyer I want to be able to pay with four types of credit cards (VISA, Mastercard, Diners Club, American Express).
There is a dependency (the first story must be implemented before the latter) but we might have small enough stories, provided that building the necessary plumbing for credit card processing isn’t too dominant in the overall effort.
Splitting by role
Last but not least, we could think about the user story at hand from the perspective of different users and the value to those users.
Let’s say we’ve got this universal story about error handling:
user friendly error messages
detailed stack trace in log file
unique error code displayed to user and in log file
Now, getting an error message that the user can understand probably doesn’t make him happy but certainly reduces the degree of frustration if his understanding of the situation improves.
The detailed stack trace and unique error code on the other hand aren’t really something the user would specifically appreciate. Their value is for the programmer who wants to be able to locate the source of an error as fast and easily as possible.
In other words, there’s two distinct users involved in this ambiguous, two-word “user story” – the user and the programmer. Splitting along this division, we might get the following three smaller user stories:
As a user I want to see an error message I can understand when something goes wrong.
As a programmer I want to see the full stack trace in the log file for any exception thrown during runtime so that I can better debug error situations.
As a programmer I want to show the user a unique error situation identifier so that I can locate the relevant portion of the log file faster and more reliably.
Each of these stories is valuable as such and independent of each other, which is nice. This example also nicely illustrates the value of the explicit “as a role I want something so that benefit” template. If we would’ve tried to write the original user story using the template, it would’ve been obvious that we’re talking about things that are valuable to two distinct roles – a clear hint at the chance of a split.
Another cue that we’re seeing in the original story is the bullet list. Sometimes you can simply look at a story and identify a log-hanging fruitsplit by scanning for keywords such as “and”, “or”, periods and other kinds of separators.
I’ll stop writing now. It took me a lot longer than I thought to get all of this out of my head but I hope it’s useful. Perhaps needless to say but I’d appreciate any feedback, suggestions, pointers, etc.