It’s not uncommon for a software engineer to find themself blocked. The reasons might vary: it could be a high uncertainty, when it’s unclear how exactly to implement the feature; or it could be a tech decision to take having multiple options with their own pros and cons. With this article I want to share the way I take decisions in such cases and how it might help you to unblock yourself.
Nowadays Agile is not a buzzword anymore. Most software development companies claim to follow it, and many do that indeed. But for some Agile is no more than a set of ceremonies and working rules like having a scrum board, sprints and tasks estimated in story points. People are doing it just because it’s trending. In some cases it just being enforced on the engineers from their management without any attempt to explain how exactly it’s going to help them. Some engineers even complain about it, because now they have those “useless” stand-ups where they feel like wasting their time.
With this article I’m not going to address any of those topics. But if you do feel like you can relate to some of them, I hope that by the time you reach the end of this post you will find Agile being your ally at least to some extent.
A few years back I used to work in one of the biggest tech companies in Russia. It wasn’t a young company like Google or Facebook, but rather an old (more than 170 years) enterprise. It was huge, with lots of departments and projects, and it was slow. I’d say while working there we rarely delivered a feature in time. And while the release process there was slow and tedious by itself, taking in some cases up to a few months, we – software engineers – were definitely contributing to the delays as well.
But we didn’t do that on purpose.
Being a good software engineer
Any fool can write code that a computer can understand. Good programmers write code that humans can understand.Martin Fowler, 1999
There were many smart software engineers in my team. They were people who loved their job, and who loved to write beautiful, elegant code. Because in many ways code – is an art, and engineer writing code – is an artist. You have to come up with abstractions there. You have to write it in a way that other people can understand it. And it can definitely invoke an emotion in the person reading it, be it a bad or a good one. Preferably a good one.
I believe that most of the people who write code are really passionate about it. They care about it. Because it’s like a child to them, and you only wish the best for your child.
And this is why within my team we could spend hours (and this is not an exaggeration, quite literally hours) discussing how to name a class, or a method. Or how to better implement it, so it would be simple, readable and maintainable.
The same goes to code review, each member in the team was a very picky reviewer. Sometimes review of a single PR (pull request) could take days, because we were trying to come up with a better implementation or a better naming. Not because we were evil or wanted to annoy each other, but because we really cared about what we do.
Another reason for delays was dealing with high uncertainty. Sometimes stories or tasks that we were getting from our PM (project manager) weren’t well defined. Or while working on them we might identify that we’re not sure how exactly to implement the feature. In that case we would typically put the story on hold, so the PM or another team member can do a better research of the topic. We believed that we can’t deliver a feature unless we know for sure the exact expectation for it.
Eventually it all contributed to feature delivery delays. But since we were working in a huge and slow enterprise, everyone there was used to delays, so nobody really cared much about it.
And we were actually trying to follow agile there! We had all the ceremonies, sprints, a scrum board and a cross-functional team. Bet were we really agile? I wouldn’t say so.
Here I must also say, that in around 3 years of me working with that team, we were working on the same project for all that time. It’s not good or bad on it’s own, but it has definitely affected the way we were treating the project, because we didn’t expect it to ever reach any logical end.
Then I moved on to working in a startup. And in around 1,5 years of me working there I’ve managed to work on 3 different services, one post-launch and delivering the other two. We had a team setup very similar to what I had at my previous job. We were also following Agile methodology and having the same formal attributes of it. But in half the time we’ve managed to deliver almost 3 times as much value. And even though some of those service weren’t as feature rich as we initially wanted them to be, I’d say the did the job just right. But how did that happen? What was the reason for such a striking difference?
I think one of the key reasons for that was time constraint and lack of resources. There were many projects planned and quite not enough software engineers to work on them. So, when we were starting to work on a new service – we knew that at some point (typically less than a year) we would have to switch to another service. And that meant we have to be very careful with the scope of the project in general and every feature in particular.
YAGNI stands for You Aren’t Gonna Need It. This is a software design principle that encourages you to focus on what’s important right now, and not tomorrow or next month, or year.
Typically during inception into a new project we were planning lots of features to make a really nice service. But then we had to apply time constraints. I believe it is very important to ask yourself a few questions about the feature at that point:
- Do we really need this feature?
- Is this feature going to be used by anyone?
- If yes, what makes us think it is going to be used? Do we fall for assumptions or do we have a hard proof?
- What is the smallest part of the feature that we can deliver and still provide value?
- How much effort would that feature require to develop?
And it is also very important to be pessimistic with your estimations. Especially for software engineers. Because most probably the PM in your team doesn’t have expertise to be able to estimate time required to deliver a feature. Moreover, the PM will probably try to push for more features and it’s very important to stand for your estimations and try to keep the scope as small as possible at least for the first release. You can always include more features with the next release. This is where agile practices actually come in handy.
Iterations for the win
Apart from other attributes of agile, the core one in my opinion – is iterations. This is what makes it powerful. Instead of having to develop all the features before a single grand release, you can do multitude of smaller releases until you reach your goal – feature completeness. And the same applies not only to the project as a whole, but to any feature of that project.
This is what allows us to actually release only the minimum viable fracture of a feature. Because it’s not the final release, we’re doing iterations and we can always improve and extend the feature later. Basically, this is all about doing an MVP – Minimum Viable Product. MVP – is a concept coming from the Lean Startup methodology. For some reason when people talk about Agile they rarely mention Lean Startup, and I believe in software development those two methodologies go hand in hand.
The Lean Startup provides a scientific approach to creating and managing startups and get a desired product to customers’ hands faster. The Lean Startup method teaches you how to drive a startup-how to steer, when to turn, and when to persevere-and grow a business with maximum acceleration. It is a principled approach to new product development.http://theleanstartup.com/principles
There’s a lot to cover about lean startup, probably even too much for this single article. One might say: “this is something about startups, and I work in a well-established enterprise, this is irrelevant in my case”. And will be very wrong to say so. We’ll get back to this a bit later, for now let’s talk about what is an MVP and what does it have to do with the lean startup.
A core component of Lean Startup methodology is the build-measure-learn feedback loop. The first step is figuring out the problem that needs to be solved and then developing a minimum viable product (MVP) to begin the process of learning as quickly as possible.http://theleanstartup.com/principles
Basically, when you start a new business or a new project – you’re trying to solve some problem. At first, you don’t have a hard proof the solution you came up with will really work or will be in demand by your potential customers. Therefore, you only have an assumption that your solution will work and be in demand.
Before you invest lots of money and time into your project, it is crucial to validate your assumption.
And the best way to do that – is an MVP. You can develop a very basic implementation of your solution, or maybe it will be just a part of it. Basically, anything that will help you validate your assumption. Once you have your MVP you can start offering it to you customers and getting feedback. In the best case you was right and your solution is popular among customers, then you can start improving it step by step. In the worst case, people are not interested in your solution, but you learned that before you spent all your money and wasted too much time on it, so you can try something else.
Let’s have a simple example here.
Hole digging company
Once upon a time there were two brothers: John and Gary McShovel. Both were really good at digging holes and loved doing it. And both of them believed that the world will become a better place if every person will have a deep large hole in their backyard.
Gary asked his parents and friends if they want a hole in their backyard, and they were very positive about that. Gary thought that is a good enough confirmation that all people in the world want to have a hole in the backyard, so he took a loan from a bank to start a hole digging company, hire some people and start an ad campaign.
John took another way. He heard of the Lean Startup methodology, so he knew about customer development and MVP. He wanted to prove his assumption that everyone would love to have a hole in their backyard.
Gary believed that a perfect hole should be 4 meters in diameter and 8 meters deep. And since his friends and family were keen to have a hole in their backyards, he decided to start with them.
John’s perception of a perfect hole was the same as Gary’s. He offered a few people to dig a hole for them and they agreed. Although, John decided to start with an MVP hole, that will only be 1m in diameter and 1m deep. So he dug a hole for his customers and gathered feedback from them.
To much John’s surprise, his customers weren’t very enthusiastic about the holes. Turns out they didn’t actually need them. But what they also let John know, is that they would actually like to have a pancake from time to time. Who could’ve guessed that not every person in the world shares John’s love for holes? At least, John didn’t waste all his energy digging holes. And luckily for everyone, pancakes is another John’s passion.
When Gary dug a hole for his friends and family he learned that in fact they also didn’t really need it. It turns out they just were trying to support Gary and be nice to him. So now Gary had a loan, a hole digging company and no customers.
John did a pivot, and baked a few pancakes for his customers. This time he also started with an MVP, a simple plain pancake, one for each customer. Then he collected feedback from the customers. Turns out most of them wanted to have a pancake with chocolate flavor.
John had repeated the process multiple times: trying a new pancake “feature” and improving upon the feedback.
He did assumptions, some got proved, some got discarded. But he knew he was moving in the right direction.
And just a few months later John was running a successful bakery!
And Gary went bankrupt.
Treat every feature as a startup
Getting back to the question of how could all that be relevant for an enterprise. I believe the best way to develop a new feature – is to treat it as a startup of it’s own. Treat it like a new product. Where you start with an MVP, with a very basic feature implementation just enough to validate your assumption about who and how will be using it. It is something you can do regardless of how big, old or inert the company you’re working at. And it is very important to collect feedback about how the feature is used. Without the feedback there’s no way to validate your assumption about the feature.
This way you don’t have to worry too much about uncertainty, because with every iteration over the feature you’re going to reduce uncertainty.
It’s okay if you can’t say for sure how to implement it. It’s okay if you’re not sure if it will be used or not. Just implement it the way you expect it to be used. Release it. Collect feedback. Improve it.
And remember: a working feature, even if it’s very simple, is better than no feature at all.
Treat your code as a startup
You can apply this approach not only to the feature you develop, but to the actual code you write. When you think of your code as an MVP, and you know you can improve it in the next iteration, you will find yourself being more productive and maybe even less stressed. At least this is what happened to me.
Before I came to this realization, I was getting stressed a lot because the quality of the code I had to review sometimes didn’t quite meet my expectations. Moreover, even the code I wrote myself sometimes didn’t meet my quality expectations as well. I tend to think of the code I write as of peace of art. I enjoy it being simple, yet functional.
But a peace of art you see in museums or galleries is usually complete. It’s finished and static. It doesn’t change. While the code is not. It’s not set in stone once you merge your PR. You can improve it later.
Moreover, sometimes it’s hard to tell if the way you wrote your code is good enough. In programming there are usually more than one, or two, or even three ways to solve a problem. And it’s not always easy to pick the best way to do it. But if you treat your code as an MVP, as a startup, you don’t have block yourself arguing about the best way to solve the problem. Just think of yourself and your peers as of customers, who will be using (maintaining) this code afterwards. You will be maintaining it, and you will be getting feedback by doing so. And so you can improve it later on. And if you didn’t have to change it for a long time, then probably the solution you picked was already the best one.
Once I started treating my code this way, I found peace of mind.
Once you think of a new feature as an MVP, you will naturally try to reduce the scope of a task to minimum. And with that comes another advantage – the smaller the task, the easier it is for the team to estimate it.
Now, let’s do a little exercise.
Imagine we have a weighing scales (weighing balance) with 2 bowls and 8 same looking balls, but one of them is heavier than the others. How many times you need to weigh the balls at minimum to find the heaviest ball?
The options are:
- I don’t need the scales, I’m feeling lucky!
- One time.
- Two times.
- Three times.
- Four times.
Give yourself a few minutes to think about the problem before scrolling down.
The problem with this exercise is that from the description we only know that one ball is heavier than the others. I.e. there’s one ball there that is the heaviest. But it’s unclear if the rest of the balls have the same weight or not.
And this is a perfect illustration of how development requirements are sometimes.
You can try to reach whoever has provided the requirements and try to clarify them. Or you can ask your PM to do so. But that would take time. And for all that time the developer will be blocked waiting for clarification.
The approach above with clarification is how we would typically do that if we follow the waterfall approach to development. But instead we can be agile.
We can make an assumption that the rest of the balls have the same weight. And therefore our implementation of the problem solution can be quite simple. We can deliver this solution and validate our assumption. If we’re lucky and our assumption was correct, then our customer will get a working software. And we didn’t spend too much time trying to implement a solution that might be more flexible (will support other ball configurations), but without any need for that (the lighter balls will always have the same weight).
This is what what the lean startup is about. And this is what agile is about.
Deliver -> get feedback -> improve -> repeat.
Don’t waste your resources on features that no one needs.
There are cases when you can’t afford to deploy a feature before you’re 100% sure how the implementation should work. For example when you’re dealing with finances. You can’t afford to reduce uncertainty at the expense of your company or your customers.
But even in that case you can try to reduce the scope as much as possible when delivering a first version of the feature, so you can learn how the customers use it and improve.
In Russian we have a saying: “не откладывай на завтра то, что можно сделать сегодня”. In English it will sound like: “Don’t delay what you can do today”. But I believe with development it should be the opposite way: delay as much as possible to keep the scope small.
As you can see, the lean startup methodology and agile methodology go hand in hand. Or rather, this is how both of them can be used most efficiently. Many things I wrote above are relevant to the extreme programming. If you find this article useful, I recommend familiarizing yourself with the extreme programming. Hopefully, it might even help you remove some stress from your programmer’s life.
To summarize the article in a few action points, this is what you can do to unblock yourself:
- Don’t waste time arguing for the best solution
Just pick the simplest one to implement and go with it, so you can collect feedback and improve.
- Start every feature with an MVP
Don’t waste your resources developing a huge and complex feature unless you have a hard proof people will use it.
- Keep iterations in mind
The code you write is not set in stone, you can always improve it with later iterations.
- Don’t try to reduce all uncertainty beforehand
Learn from how customers use your product. Don’t try to predict how they will use.
- Think of your code as of product
Where you and your peers are the customers, and it’s maintenance – is how you use it.