Decomposing work

Where we learn some more about how to slice work into smaller pieces, perhaps so small we can deliver many a day.

Reducing the batch size of delivered work is one of the most important things we can do to drive improved workflow, quality, and outcomes. Why?

  • We have fewer assumptions in the acceptance criteria because we had to define how to test them. The act of defining them as tests brings out questions. “How can we validate that?”
  • We are less subject to hope creep. We can tell within a day that we bit off more than we thought and can communicate that.
  • When we deliver and discover the story was wrong, we’ve invested less in money, time, and emotional attachment so we can easily pivot.
  • It makes us predictable
  • It helps to reset our brains on what “small” is. What many people consider small turns out to be massive once they see what small really is.

The above comes from the Dojo Consortium’s page on work decomposition. There is a wealth of information if you head over there. This is an attempt to summarize some of the highlights with links to more in-depth articles.

Outcomes and output

Differentiating between outcome and output is important when we look at how we decompose work. This is due to how we need to decompose each kind.

An outcome is something we have identified that will help someone fulfill a task, reach an objective, change a behavior, and so on. It describes the underlying drivers for making a change in our software.

An output is an artefact of some kind. It’s a tangible thing. It can be an API or a UI component. Output may not deliver the outcome we want to achieve. But we can hope it does, figure out a way to gauge if it’s successful, and use the data we get back to decide if the outcome has been achieved.

Another way to frame it is that outcomes are what guides what you are going to work on, output is the result of the work you do.

What is also important to remember is that the output has no value unless it archives the outcome. Output has a very short half-life and quickly becomes a liability. This is because every output you create increases the products inherent complexity, making it more difficult to change and maintain.

Decomposing outcomes

Epics, feature and user stories should all be centered around user outcomes. Decomposing them is all about figuring out how we can take the smallest possible steps to iteratively discover just how little behavior we can change or add to achieve the outcome we aim for.

For a good explanation on the difference between incremental and iterative, read Steven Thomas’s post.

Using the methods described in From Road Map to User Story will help you get from high level ideas to more bite size chunks of change.

Once you have managed to get to some form of user story type size it’s time to look closer at defining the more exact requirements of it, and also most of the time to break the story into several stories. The Work Decomposition page will bring you closer to ready to start work. If you already have a fairly good grasp of this the next step may be to use BDD to help you drive the conversation. One very good way to further improve on your stories and surface even more unknowns is to use Example Mapping to really get into the details of each requirement.

When you have gotten this far in your decomposition you should have a clear idea of how each of your user stories brings value. You probably also have a good idea of what output is needed to achieve the outcomes of the stories. From here we move on to making this new output seamlessly fit into the current product. We do this by incrementally adding it. Which bring us to the next topic.

Changing behavior vs. changing structure

Many teams struggle to get enough time to tidy their code base. This results in what is known as technical debt and can cripple the development of a product to the extent that it no longer becomes viable to continue supporting it.

One way to avoid this issue is to ensure that we understand the dynamics between structural changes and behavioral changes in the product and how each supports the products sustained viability.

When we have a new idea for the product this means there is a need to change the product’s behavior. However, a well crafted product is unlikely to have a structure that will fully support the behavior change (Kent Beck digs in to some of the dynamics here).

This means that whenever there is a need to change behavior there is also a need, and a very clear value, in changing structure first. Just enough structure to make the new behavior fit in easily mind.

When you look at one of the (I hope rather small, like 1/2 to 1 days work) user stories from the previous step you can now start to think about what the code and architecture should look like to make that change. Here is also one of the secrets in being able to slice a vertical user story into 1/2 a day of work. Are there parts of your code that is at odds with it. When you have identified such areas, make the structure fit the new change. If possible, allow each change to go all the way to production. Or at least allow it to go as far as possible. This is the safest way to see that you have not changed behavior.