Slicing your development work as a multi-layer cake
By: Luis Mizutani
In Agile projects, the goal is usually broken down into discrete units of work that describes a feature or ability to perform an action from an end-user perspective. These blocks of work are usually referred to as ‘user stories’.
That leads us to an obvious question: what is the best way to break your work into user stories? Like so many other things in life, the answer to that is: it depends.
We often joke at work that this is a typical answer from a consultant. But the reality is that there is no ‘silver bullet’ for perfecting your story creation process.
That’s not to say there isn’t useful literature exploring how to write user stories. It’s just that no theory will teach you when to apply any particular method. Breaking down work into user stories is one of those hard things that you will only learn with practice.
That’s the bad news out of the way. The good news is that there are a number of techniques you can use that increase your chance of creating stories that work.
One of the most popular frameworks for story creation works on the premise of thinking about the user, scope of work and the value this work will ultimately deliver: “As a…. I want to… so that I…”. It’s a good start, but it doesn’t provide too many insights into how to break down the work into small, functional pieces that will deliver value, enable tests, help on product evolution, and provide flexibility for scope change.
This is where the ‘multi-layer cake’ comes in. The idea was first espoused by Bill Wake, in 2003. The concept says:
Think of a whole system as a multi-layer cake, for example, a network layer, a persistence layer, a logic layer, and a presentation layer. When we split a story, we’re serving up only part of that cake. We want to give the customer the essence of the whole cake, and the best way is to slice the cake vertically through the layers. Developers often have an inclination to work on only one layer at a time (and get it ‘right’), but a full database layer (for example) has little value to the customer if there is no presentation layer.
- You cannot try the cake before it’s fully done: slicing the cake horizontally means delivering your system layer-by-layer. The downside of this approach is that users can only experience the system when it’s fully done. An Agile approach would favor delivering the minimum set of features needed to generate a return on investment. It’s about maximizing flow and value.
- You may not like the cake when you try it: the entire cake must be baked before the customer realizes that the cake he/she got is not exactly the one he/she wanted. In other words, the feedback loop is long, which increases the risk. Moreover, increasing the cycle of feedback is the opposite effect we want to achieve when adopting Agile methodologies. The whole idea is to be able to learn and use this knowledge to make changes as the product evolves. An essential source of learning is exactly the knowledge coming from user/customer feedback.
- You cannot choose the slice you want first: it is almost impossible or impractical to align all horizontal stories across different layers and adjust them to a constantly changing business priorities. Assembling your system layer-by-layer reduces your flexibility. It makes it harder for Product Managers to reorganize the product roadmap. Project Managers will struggle to cope with dependencies and manage smartly the team’s capacity. Both are pretty common on product development projects. The integration of layers developed independently can also turn into a nightmare and impacted negatively the cost, time and overall quality of the project’s end result.
The theory is all well and good. But to create stories effectively, you’ll need to balance theory with practical experience. The ‘Invest model’ is a nice example of the pitfalls of just doggedly following theory. It states that good user stories should be: Independent, Negotiable, Valuable, Estimable, Small and Testable. It is important to realize that this is the ideal world.
When talking about ‘user stories’ and the ‘Invest model’, I’ve seen many instances where the value of stories is overemphasized. As a result, it appears that every story — with no exception — has to deliver a value by itself.
This rigid view may fail, for instance, when we are talking about the work to build up a communication flow, where multiple systems have to talk to each other. If excessive emphasis is given to the value perspective you may end up with a very long and complex story, where the outcome is only achieved when the entire flow is working. From a value perspective this makes sense, but from a testing perspective, this can be a nightmare. Another downside, in this case, might be in terms of the team’s motivation, as long stories are boring, and encourage concentration of knowledge and creation of silos within the team.
For that particular example, placing too much emphasis on value also prevents teams getting quick feedback, both from users and third-party systems. In such situations, you may prefer to break down the work into units using the level of complexity as your main driver. This means going from the simplest piece of work to the most complex one, growing in sophistication gradually and based on regular feedback.
In the example below, we will use a story to create a new feature for a website that sells travel tickets.
“As a user of XYX travel site,
I would like to see the list of flights between the two selected cities, with total, tax inclusive prices
So that I can choose option that suits myself best”
It seems a simple task to create a list with information to be displayed in the website’s UI. However, generating the right information demands a lot of logic, involving multiple layers and sometimes multiples systems, as shown below:
The work is much bigger than it seems, and when development starts, it can grow in complexity and effort even further. By the end, your user stories may be insanely long. Long stories block other’s stories and increase client’s anxiety. Moreover, they can hide problems affecting team’s lead time and make it difficult to get the right sense of the team’s capacity.
When story is too big, there is a natural tendency to slice it horizontally — and we don’t want that. We still want to keep stories transversal. But how to do that without creating huge stories?
These are not ‘cake recipes’, but some useful strategies you can use when breaking down work into stories.
- Workflow steps
- Business rules
- Happy / Unhappy path
- Data types of parameters
- Input options / platforms
- Vague terms and conjunctions
When breaking down a workflow or user journey into smaller steps, be careful with the level of granularity you use. A story can cover a single step of your workflow, as long as it provides something useful to users/customers. If you think a single step does not provide any business value per se, it is likely that you should group more than a single step to create your story.
Another option is to break down your workflow differently. But be careful. As we previously highlighted, sometimes it’s better to deliver each flow steps at a time with no individual value.
When working with complex workflows, a good strategy is to start from a very basic and functional flow and add new layers of complexity iteratively, selecting your next story or improvement based on feedback from users. You can also isolate different branches within the same flow, such as happy and unhappy scenarios that will be described further on. Below we illustrate that concept applied to a purchasing workflow for an e-commerce website.
When breaking down your work using business rules as guidelines, try to distinguish between the rules that cover the majority of cases from the ones tackling edge cases. Clients often are so concerned to map all possible cases, that they forget sometimes an edge case can be treated with a cheaper and alternative solution.
Start from rules that will cover most common scenarios or your main assumptions (hypotheses) and leave the very specific ones to the next development cycle.
Testing basic rules in real life situations is one of the best approaches to extract data and information to identify alternative scenarios you should cover — and the additional rules that you need to implement.
Below is an example of rules that an e-commerce website can use to determine if an order will be rejected or not, based on the cost or operational complexity to deliver the product. We start by assuming that our basic delivery costs will be covered with sales over $5. We also assume that the volume of foreign orders are slow and do not compensate a rule to treat them. If we don’t start receiving a high volume of orders coming from abroad, then the rule to reject foreign orders may be a waste of time and effort. But in order to know that for sure, we need to have real-world data.
The ‘happy and unhappy path’ framework can help break down stories, especially when other approaches aren’t working. It is important to highlight that in some cases you will need to have a manual process in place to deal with unhappy paths until you have it implemented.
For example, you can provide users the ability to create a login through a simple registration functionality with no editing mode. Until you provide users the ability to edit their login, you will probably need to have an alternative solution in place, such as a support email that is sent to someone on your team. Of course, this won’t scale or provide good security, but it’s a stop-gap solution.
Defining data types is an ideal way to break down stories when developing search functionalities or registration forms. User research enables you to decide the criteria to use when creating search filters, for example.
When it comes to registration forms, start with mandatory information or that which will help validate your main assumptions. Another example is implementing search attributes or filtering options for a search result page. This last case is shown in the image of example below.
In a responsive world, it’s natural to cover more than a single platform at once. But you can simplify things by focusing on one platform at a time (see below). This logic can be applied to break down your work into stories. Use data from your audience to support that decision, for instance, start from the platform that has the highest audience. Ideally, you want to use this strategy in early phases, when you are still validating the design and basic product features. If you leave decisions around responsive design too late, you may spend more time and effort to make your product responsive.
You can also breakdown stories, by making high-level ideas more specific. This allows you to make smaller stories, with benefit we already explored, such as speeding up feedback and value. Another benefit is that you provide developers with a clear idea of what needs to be tested for the story to be considered done.
We can consider the following definitions of these terms:
As a frequent traveler, I want the weather application to store several days of weather data and display it offline so that I can see the forecast when I arrive at my destination, even if I don’t have cell service.
1. Store the next day’s weather data
2. Store the next five day’s weather data Conjunctions
As a return user, I enter the option to save a credit card number and select it for future purchases, so that I don’t have to type in all the data each time I buy.
1. Save credit card number to my profile
2. Offer the option of using a saved credit card number on a purchase. http://www.caroli.org/the-onion-method-by-lourenco-soares/
Originally published at www.thoughtworks.com on September 19, 2017.