A lot of tiny steps
There are few truths in software, but one is that it is easier and faster to solve a lot of small problems than to solve one very big…
There are few truths in software, but one is that it is easier and faster to solve a lot of small problems than to solve one very big problem.
This post is not about football but software, in any case I like an idea that usually comes from some football coaches.
I usually like to say that I’m “cholista”, Cholo Simeone is the coach of Atlético de Madrid. I’m a fan of Real Madrid, but when any journalist asks Cholo about his plan to win the Spanish Football League, he always answers that the plan is playing match by match.
This idea, match by match, it’s in my opinion the key to solve big problems. As developers, we are always managing expectations. The typical example is when someone comes to us and ask for a feature, they want to know when the feature will be done. The problem with software is more complicated than football because in software we are not in the brain of the client, we need to understand what is needed to be done and once this is clear we can think on how much effort it is.
We are very, very bad estimating features because it’s very difficult to understand all the things we need to do to succeed, uncertainty usually is high. But we can use this truth, that is easier to go step by step. This gives us the possibility to decide next steps based on the feedback retrieved from the previous ones. So one key is discovering smaller problems to solve in the big feature to implement, we could do as Cholo, the plan is just the problems we have to solve, in his case each match.
If you think on any Agile/Lean methodologies, all of them talk about small, frequent increments. Each of these small increments have a lot of benefits:
Less risk, the number of things that can be wrong, is reduced if we change few things.
They are faster to put in production because the number of details to remember and take into account are low (cognitive load is low).
They push us to revisit one and again our process to go to production, because as we develop faster we also need to go faster to other steps in the process. It will be easier to identify the next bottleneck in the system (there is always a constraint in the system https://www.leanproduction.com/theory-of-constraints/)
The plan
When we talk about the plan in Agile we are talking about User Stories.
A user story is a promise for a conversation.
https://en.wikipedia.org/wiki/User_story
The plan is a set of user stories that will change as we go, receiving feedback from clients. As small these user stories are, as fast we will receive feedback, so we will be able to adapt better to what our clients want. Clients need to see tangible things to understand what they really want.
But a good user story should be:
“I” ndependent (of all others)
“N” egotiable (not a specific contract for features)
“V” aluable (or vertical)
“E” stimable (to a good approximation)
“S” mall (to fit within an increment)
“T” estable (in principle, even if there isn’t a test for it yet)
These rules mean that you cannot split user stories once and again, there is a limit, (it’s key to stress the limit). Can we continue simplifying the problem in small steps?
Some teams split user stories in technical tasks, to allow them to follow working in small steps (communicating different specialist). I think this is a very bad idea, more details here.
There is an alternative, trying to continue simplifying the problem in another dimension, when we are developing.
Development
We (devs) usually think that we have to ship the whole user story at once. This is not true, we work with code, and we can do almost everything with our code.
So the rules change here, we only need to activate our code to enable the user story in production, but we can ship smaller parts if we are able to hide these intermediate steps to the final user.
This allows us to create a plan to implement the user story, but an Agile plan, the same that we did with user stories. We can start splitting our user story on small subproblems that solve one part.
If we solve each one of these small problems, we will be able to solve the whole story. After each subproblem solved (vertical subproblem of the user story) we can receive feedback from our team, this is great to understand iteratively better what we have to do.
But to work in this way we need to be sure that each of these subproblems have really been fixed, writing automatic tests is the best way to achieve this. Talking about tests is a very interesting subject but incredibly big, some ideas here.
Evolutionary design is a great way to handle the complexity introduced by our iterative approach to solve problems.
Sometimes when we are trying to fix one of these subproblems we realize there is another one, this is key, because as we go we are able to create new user stories (promises of a talk) to solve these new discovered cases.
So which tools/practices can help us to be able to work in tiny steps?
User story splitting We will be able to split stories in smaller stories.
TDD it will help us find the subproblems to divide our user stories, to define them like tests and finally to solve them.
CI/CD (trunk based development) It will help us to support our small steps and move them to production with confidence. Share the code quickly in our team.
Branch by abstraction, it will help us to create different behaviors and maintain them apart from the old ones. This reduces the risk of introducing bugs while development is still on progress.
Evolutionary design to control the complexity introduced by the small steps we are introducing.


