This is a concept my team has been working on implementing in our refinement sessions. Talking through some of the general ideas with my friend, I feel like I was able to conceptualize the problems and solutions pretty well and wanted to expand on the approach here.
Everything I'm talking about here is very heavily influenced by the book User Story Mapping by Jeff Patton. My team has read this book together, focusing on a couple chapters a week and meeting to discuss the ideas and how we think we can work them into our processes. This book and approach have been super valuable, definitely give it a shot!
Anybody that's heard of or practices Agile will be pretty familiar with the concept of a user story. Simply, a user story describes a software feature from the end-user perspective, hence the name! In a user story, you try to describe who the story is for, what is going to be delivered, and why it matters in the first place. It's all about conveying the value of what's going to be created. A user story has acceptance criteria, which are basically a set of requirements that need to be met in order to consider the story complete.
User stories can be broad, that's okay! They can and should be broken down into workable chunks by the development team when it makes sense.
Developers generally approach problems by thinking about how they should be implemented. Consider a story involving a multi-tiered system; you may have a presentation layer, a business logic or backend layer, a persistence layer, and maybe a couple more! Naturally, this leads to slicing the user story horizontally across these layers: a story for frontend, a story for backend, and a story for the database work.
The major problem with this approach is that dependencies are inherent in the way the stories are constructed and, as a result, it takes a long time for any actual value to be realized. You don't have anything releasable to show customers, stakeholders, or users for potentially several sprints. You can't deliver a half-baked cake.
Additionally, you'll be introducing technical debt in terms of toggles for features that aren't production-ready and workarounds needed for part of the feature to work while others are still being worked on. Estimating the size and deliverability of the story hasn't been made any easier and by working the whole story across each horizontal slice, you haven't allowed for any iteration based on user feedback or left room for reprioritization.
First and foremost, we want to quickly add value for the users and stakeholders. We can do this by looking at which independent pieces, implemented end-to-end (vertically) across all of the layers mentioned before, compose the larger user story. Identify the value and risk of each piece and prioritize accordingly.
This approach will let you iterate more quickly as features will reach end users and allow them to provide feedback. Unknowns and dependencies don't block progress on the larger feature as pieces can still be worked on and deployed. Your team will be able to respond better to changes in priorities, making you more agile as a result. But, most importantly, you'll be delivering measurable value to your stakeholders and end-users more quickly.
This is pretty abstract and a huge change in perception! Let's practice with a real-world example.
I work on a mobile team. Ahead of our previous sprint, we were given a story resembling the following:
As a user, I want to know when updates are available so that I can get the latest features and fixes
The acceptance criteria included:
- A banner to be displayed on the home page indicating that a new update was available
- Cosmetic changes to the existing update link in the user profile to make it stand out more
- Both the banner and existing link should navigate to a release notes screen showing the latest changes and links to download the updates
This story isn't terribly large, but couldn't be delivered in a sprint considering there were other items we wanted to work on. It did turn out to be pretty good practice for slicing stories vertically, though!
As a team, we identified that we could add value quickly without delivering the whole story. Taking into account the current state of the app, where the existing update link leads directly to the download, we decided the update banner added the most value to the user. By making the new banner behave the same as the current link, the banner and release notes screen are independent, and can be separate stories. Likewise, the change to the current link adds value independently, and therefore becomes a separate story. This "big" story just became a three small ones that we can prioritize separately!
Admittedly, we did get carried away. We created a fourth story, originally, for updating the navigation from the banner and link to the new release notes screen. Navigation itself wasn't really independent of the release notes screen, so it made sense to add that story back into the story covering the release notes.
The release notes screen was reprioritized (and has yet to be pulled into a sprint). From a development perspective, we have small, easily testable, and easily reviewable chunks of code. From a stakeholder perspective, we've made progress toward delivering the full feature and arguably have carried out the goal set out in the user story.
We were able to deliver measurable value to the end-user without implementing the full story.
You can't deliver a half-baked cake, but you can deliver half a baked cake.
Overall, our team is very happy with the outcome. We'll continue to practice and refine the process, and hopefully bring it to other teams as well.