Pair programming - the elephant in the room
If you and your colleagues are into pair programming you should continue doing so even after introducing async practices. However you should optimise how you practise pairing.
- Design your work patterns for flexibility. Try the baton-pass pairing routine.
- Use the right pairing tools, otherwise the dev team will struggle to pair efficiently. That in turn can be morale and productivity sapping.
- Everything we've discussed thus far about personal discipline becomes even more important. You're now responsible for two people's time.
- Be pragmatic. You don't always need to pair. Find ways for people to work solo and learn from their own mistakes as well.
When you have a hammer, everything looks like a nail. When that hammer is asynchronous work, we may think of making everything in our work lives asynchronous. Calm down. Take a deep breath. We’re going to take a break from that and address an elephant in the room. Pair programming is amongst the most frequent synchronous activities that agile teams, especially those that follow extreme programming (XP), practice. To the uninitiated, here’s a definition.
I don’t think that I’m overstating it when I say that pair programming or pairing is a controversial topic. There are two viewpoints you’ll hear about this.
The zealots | The naysayers |
---|---|
“Pair programming is the only way to write high quality code.” | “Pairing is an unproductive waste of time where we make two people do the job of one.” |
While the truth is often nuanced and falls somewhere in the middle of that spectrum, I disagree with the naysayers. Pairing is by far the most productive, synchronous activity an agile team performs. I can’t do much better than my colleagues Birgitta and Nina when explaining the benefits of this activity. For anyone who thinks pair programming halves the productivity of developers, Martin Fowler’s flippant quip is a suitable response.
"That would be true if the hardest part of programming was typing".
The biggest benefits of pairing that I’ve seen on the teams I’ve worked on overlap with what Birgitta and Nina explain.
Constant code review. Two people working together keep each other honest. You’re on the constant lookout to refactor code as you go. Your pair provides you a safety net to avoid cutting corners. The two of you can hold each other accountable to follow your team’s coding standards.
Knowledge sharing and mentoring. You can document a codebase to death, but a new developer will never have the confidence to navigate it until they’ve actually contributed code to it. As codebases get larger, the barrier to entry for new developers increases and it gets more daunting to write code. Pairing reduces this barrier to entry by helping new, even inexperienced developers learn about the structure of the code base. Constant rotations help seasoned programmers share their skills with less experienced developers. Even experienced developers can learn a thing or two from a fresh pair of eyes. Feedback in the flow of work improves resilience in the team.
Team bonding and camaraderie. This is a benefit of pairing that we often overlook. Working in a paired setting helps you observe your coworkers at close quarters. Not only do you benefit from experiencing diverse styles of problem solving, you learn about each other’s quirks and find common ground you may have never chanced upon otherwise. It’s tough to place a dollar value on camaraderie, but anyone who has worked in a team knows it has as much value as any productivity measure.
There are challenges, of course, and Birgitta and Nina’s article cover those too, but that’s not the focus of this article. The benefits I mentioned are important for co-located and distributed teams alike. So if pairing is the most important synchronous activity for a distributed team, how do we weave it into a remote-native way of work? I have four things I want you to consider.
Design for flexibility
That people can work the hours that make the most sense for them is one of the biggest features of remote work. This is at odds with having to “sync up” with someone and to pair with them. To me, it’s not an intractable problem though. There are two ways to get around this problem - one that I prefer more than the other.
You can institute “core hours” on your team, when everyone’s available to pair. While this makes things predictable, it’s heavy-handed. Every day isn’t the same for every single person, so you will end up making life difficult for some people on your team if you take this route.
I prefer another option. Leave the timings down to the individual pair. Let them figure out the hours that work well for them to sync up. This kind of decentralisation makes your team’s processes, in the words of Taleb, anti-fragile. Regardless of the events of the day, two people can easily figure out how they want to work together.
I’ve seen this pattern work remarkably well when I was working with an East European software development company. I call this the baton-pass pairing routine. The dev that started their day early would begin working solo. At some point, the second dev would join them and they’d have a few hours of intense pairing. After the first dev logged off, the second dev would work solo. At the end of their day, the second dev would write up notes for the first dev. That way the first dev could pick up the baton the next day. The practice of writing good commit messages made this pattern even more effective.
Use the right tools
Repeat after me. “Pair programming is not screen sharing”. Ask any developer who has tried to pair using Zoom or Teams, and they’ll tell you that the experience is nothing like sitting side by side with someone. That’s understandable, isn’t it? Once you throw in features like remote controls, video conferencing tools become laggy and inefficient. There’s no comparison with the physical setup of two developers sharing a keyboard and a screen, sitting side by side.
If you don’t have the right tools, remote-pairing will be an uphill battle. You need specialised tools to do this. The two tools I’ve seen my colleagues enjoy are Tuple and Visual Studio Live Share. I’ve also heard great things about CoScreen, but I haven’t worked in a team that’s used it extensively. Whatever you do, don’t let us business types select pairing tools for developers. Listen to your developers and let them have the pairing tool that works for them.
Encourage personal discipline
We’ve discussed this topic earlier. Effective remote work is also about personal discipline. When in a pairing session, you’re responsible for your time and your pair’s time. If you get distracted by IM or plan a meeting in the middle of a pairing session, it disturbs your partner’s flow. Pairing works when two people immerse themselves completely in solving a coding problem. It’s also as inefficient as the most distracted partner. A few years back, my colleagues at Thoughtworks created a hilarious video with several pair programming anti-patterns. While they shot the video in the office, all the lessons apply in the remote world as well.
Shun dogma
When you see the value in pairing, it’s tempting to pair all the time. Pair programming is intense and tiring - you’ll know when you try it. People will need a breather. The baton-pass routine helps with that. You may have very simple coding activities that won’t benefit from the intense code review of pair programming. These are great candidates for solo work that people can sign up for when they need a break from pairing.
Sometimes people will need to go solo, if only to build their confidence. Birgitta and Nina suggest a solution.
I hope this article makes my stance on pair programming clear. To me, async-agile is non-binary. I already told you that when we discussed the spectrum of synchronousness, but it doesn’t hurt to reiterate it. The value of being more async is also in making the truly valuable synchronous activities more productive and fun. Be it a meeting, or in this case, pair programming!