Today I want to share with you an experience that has profoundly influenced the way I think about software development. It is a story about a bunch of programmers that came together, learned to collaborate and became a successful team. And although similar stories typically feature individuals or software tools as their heroes, this story is going to be a bit different.
This story is about real people working on real projects facing real problems. In fact, there are probably dozens of stories similar to this, but this is the only one I participated in myself.
I’m sharing it in the hope that it can be of use to you, be it as inspiration or as guidance. What worked for us might not work for you, but I’d suggest you give it a try nonetheless.
Setting the stage
Some time ago my manager asked me to join another one of his teams. He was worried that they might be struggling and wondered if I could be of any help.
And no wonder he was worried! When I learned about the challenges the team was facing I was surprised that they had been able to get any work done at all! Allow me to describe their situation with a few words:
- A team of four developers that had never met or worked together before, all contributing remotely from various offices around Europe
- with all major stakeholders (design, product manager, core maintainers) being in a different time zone (a staggering 9 hour difference)
- being handed what you might call a legacy code base: lots of code, almost no test coverage, a complex web of component dependencies, painfully slow builds and a melting pot of different technologies
Sounds pretty tough, doesn’t it? Had I only known that I was going to work with such excellent individuals I could have told my manager right then that he need not worry.
Act I: Uncovering problems together
After a week or two had passed, we felt that we had gathered just enough experience to try to improve how we developed software together. Up until that point we were pretty much using a little bit of this or that methodology. We weren’t really an Agile team, nor a Waterfall one, but some strange combination of the two. Thus, we called our first retrospective.
We kept the format down to everyone answering only two questions: “what worked well?” and “what didn’t?”. Once we collected a bunch of virtual sticky notes (remember, we were an all-remote team), we picked just one of them and discussed it. Instead of blaming each other for what didn’t work, we tried to answer the question: “how can we turn up the good?”. We ended the retrospective by committing to changing only one thing and evaluating how well it worked at the next retrospective.
And thus we began to introduce a series of changes that would ultimately lead to a way of making software together that was remarkably successful.
Act II: Reviewing code together
The first thing we set out to improve was code reviews. Initially our team had started by adopting the most prevalent process in the organisation: asynchronous pull request reviews using written comments.
This process might have worked fine for the rest of the organisation, but because we didn’t work together that long yet, because the existing code base was overly complex and because we were 9 hours apart from the core maintainers, that process didn’t work for us at all. A typical pull request at the time was open for several days, contained about a hundred comments and generally caused plenty of negative sentiment. To improve the situation, we decided to do two things:
- Receive enough training to be able to merge and deploy code without being blocked by waiting for approval from someone in a different timezone
- Review every pull request together in real time using with video chat
These two changes alone had a positive impact on our velocity: we tightened the feedback loop, had better conversations and made changes immediately. Naturally, it became a lot more fun to work together too!
Act III: Writing code together
When one of us had learned about mob programming and suggested we give it a try, it felt like a logical next step to us. We had already benefitted so much by reviewing our code together, so why shouldn’t we try to write it together in the first place?
We began with two short sessions per week during which all of us worked on the same thing in the same virtual place. Admittedly, it took us a few attempts to get good at working together like that, but once we got the hang of it we worked like this more and more.
We strictly followed the one-driver-many-navigators model: the driver is the only one allowed to write code while the navigators are the only ones allowed to decide what code is being written. We allowed the roles to change freely and at any time. This forced us to explain our ideas before we turned them into code.
Eventually we worked this way almost exclusively, occasionally breaking out into two mobs. By then pull requests had become only a formality and all their problems had faded away with them. But that’s not everything: we also built up a deep shared understanding, made better quality software and, you won’t believe it, shipped more code!
Act IV: Making architectural decisions together
Over time we found ourselves talking more frequently about topics and patterns spanning the entire code base. At first we kept pushing those conversations into the future, but eventually we had to address some of them.
We therefore scheduled weekly architectural whiteboarding session in the lean coffee format. We began by listing all the topics to talk about, vote for the ones we thought to be most important and then discussed it.
As everyone could bring up topics they cared about, architecture became important for all of us. To some extend we have all become software architects.
Act V: Designing the UI together
As the project neared completion, the user interface started to fall behind significantly and eventually it became our top concern.
Up to this point we followed the process preferred by the design department: a designer shared with us a set of image files picturing various parts of the user interface along with some annotations. Questions were supposed to be asked and answered purely in writing (our designer, too, was 9 hours apart).
When it dawned on us that this problem was farily similar to the pull request problem we had solved earlier, we simply attempted to solve it in the same way: we invited the designer to join a few of our mob programming sessions.
Here, too, we were happy with the results: not only did we get the user interface back on track, but our designer also got the opportunity to finally fix all those tiny issues that had been bothering them all along.
We introduced these and many other changes over a period of approximately half a year. For every change introduced, we decided what to try, what to adopt and what to refine. We always kept a pace that was comfortable for all of us.
Looking back at these months now I’m still amazed to see that small changes over time can add up to make such a profound difference. There was no grand plan of what we wanted to change, no single individual rescuing the day and not a single highly-praised software tool. All we had was a strong set of values that guided us.
I often get asked why five developers working on one thing should be more effective than five developers working on five things. Every time I answer that I honestly don’t know, but that the results speak for themselves: We’ve shipped more things in less time and with better quality. And along the way we’ve all became better programmers.
If this article got you excited, you’re not going to want to miss the next set of articles about how to introduce pair programming to your team. So be sure to subscribe to the newsletter!