This post contains notes from Chapter 12 of Agile Estimating and Planning by Mike Cohn.
The book contains a number of recommendations, including both patterns and anti-patterns for how to split large user stories. The quotes below are taken directly from the book with the following comments from me.
How to split
Splitting on “features”
Split large stories along the boundaries of the data supported by the story
The idea here is to identify the data with which the user interacts with the system. Then split up along the non intersecting (or separable) subsets of this data. The book uses an example of an accounting system where a balance sheet could be completed as (1) a single number, (2) more detailed information, (3) total itemization. When split up into three stories following this separation the original story became more manageable.
Split large stories based on the operations that are performed within the story.
Here the idea is to identify the specific operations that a user does and split up the story based on them. Splitting up along the operations might result in a functioning product by the end of the sprint that would not be user ready, but still well presentable during the demo. The example given was of a form with a filter and a display grid, with the team deciding to implement just the filter and query, displaying the number of found rows rather than rendering the grid. Effectively the team implemented the filtering operation in the first sprint and the grid presentation operation in the second.
The same topic also included:
Split large stories into separate CRUD operations
Here the book provides a very easy suggestion of how to split on operations when CRUD can clearly be seen.
Splitting on “non-direct features”
Remove the handling of exceptional or error conditions
If the original story contains conditions that must be handled which are outside the main flow, these can be split off.
Consider removing cross-cutting concerns (such as security, logging, error handling and so on) and creating two versions of the story: one with and one without support for the cross-cutting concerns.
This feels somewhat similar to the exceptions and error condition suggestion above. The idea here is that if you can separate the user functionality of the story from extra requirements (possibly generic to many functionalities) you can consider implementing the user functionality first. This would be followed by another story that will introduce the extra (generic) functionality on top of the user functionality.
Consider splitting a large story by separating the functional and nonfunctional aspects into separate stories.
Here the author started by mentioning the anti-pattern of “premature optimization”. The suggestion here is that if you see any requirement like performance or others they can be split up.
How not to split
Don’t split a large story into tasks. Instead, try to find a way to fire a tracer bullet through the story.
I found the wording of this suggestion confusing. The suggestion however is excellent and I can’t agree more that trying to split by separating into development tasks is a bad idea. What “tracer bullet” here means is that however you split you need to have all layers working in some manner. In essence the functionality has to be demo-able.