17 Jun 2012 On Pair Programming
Working on a project that used pair programming was something that I’d wanted to try for a long time but had never had the opportunity to do. Consequently, when a chance came up to work on a project where the entire team was pair-programming full-time, I was ready to get on board and give it a go. In this post I’ll talk about my experience, some of the benefits I saw, and some broader conclusions that I reached.
More than any other agile practice, pair programming seems to polarize people and inspire strong opinions. Experience with pairing does not seem to be a pre-requisite for expressing such views. Furthermore, pair programming – particularly full-time, team-wide pairing – is probably the most difficult of the agile practices. It’s usually the last practice to be brought on board, and the first to be thrown over the side when things get rough.
Whilst there is a ton of literature out there on agile practices, pair-programming gets surprisingly little coverage. This is surprising considering the benefits espoused by advocates, and unfortunate given the numerous challenges that pairing presents. The one book I have found that is dedicated to pair programming – ‘Pair Programming Illuminated‘ – is good, but having only been written within a couple of years of the rise of XP, I’m reluctant to ascribe too much authority to it.
So let’s cut straight to it
The full-time pair-programming I have done so far has been very difficult for me. It has without doubt been the biggest disruption to the standard mode of working I have used over my career. I have struggled at times to maintain my levels of engagement and frankly, I haven’t enjoyed it as much as I hoped.
My limited personal enjoyment of pairing makes me reluctant to make any general statements about pairing in general. That’s not to say that personal preference is not important – it directly influences motivation and productivity. All that I can recommend is that – assuming that you are in an environment that supports pairing – I think the decision of whether to pair or not should be left to each developer.
That said, despite the challenges that full-time pairing presented for me, I saw some undoubted benefits. I thought I’d talk about them here, because people who haven’t paired tend to focus on what they imagine its shortcomings to be, whilst not really understanding the benefits.
Without doubt the most dramatic benefit I saw from full-time pairing was the phenomenal speed of knowledge dissemination within the team. Within a few weeks of joining the project, I had a broad understanding of most of the system that I was working on. This was impressive given the size of the code-base. Not only did I learn a huge amount in a short space of time, but I was quickly able to get to a point where I could teach others. This is both personally gratifying and beneficial to the project.
Another benefit of this knowledge dissemination was that nobody was really on the critical path. There were no lynchpins in the team, and everybody was capable of picking up any part of the system at any time and running with it.
The critical factor in achieving this rate of knowledge dissemination was pair rotation. Of course, rotation comes with it’s own tradeoffs – in particular the cost of context-switching. Furthermore, some people don’t like to rotate, especially if they’re paired with somebody they like to work with.
Ideally, we’d all get to complete a story card as a pair, and then rotate. But obviously not all pairs will finish their cards at the same time, so this rarely works.
In short, I’d recommend forcing yourself to rotate every couple of days at the most, but not within less than half a day.
Like many things, people tend to notice when bugs are present, but not when they are absent. This makes it easy for low-defect rates to be taken for granted. Nevertheless, on this particular project I was surprised by how few defects seemed to be in our finished product compared to other projects I have worked on.
I attribute much of this success to pairing. However, this wasn’t so much because of the rigorous continual code-review of pairing, but because of the intense focus that two developers can bring to testing their code. Something about having two sets of eyes running over the tests meant that the testing was really thorough. Somebody was always dreaming up a new test scenario, which would then spur on the other to come up with something else.
It helps if you’ve got a good set of testing tools and practices in place. The pair are then able to keep each other focused on sticking with these approaches. For example, if the decision has been made to take a test-first approach, knowing you’ve got another set of eyes watching you type makes it less likely that you’ll try and skip writing a test first.
Another terrific benefit I saw from pairing is that you quickly get to meet and work with everybody on a team. This has two benefits. Firstly, team cohesiveness grows rapidly. There’s no more bitching about how long it’s taking that guy in the corner to finish a particular subsystem that you’re dependent upon, because you going to be pairing with him at some stage. That means you’ll be walking in his shoes, feeling his pain, and probably discovering that he’s not such a bad guy after all. Pairing breaks down walls within teams.
Secondly, pairing allows you to rapidly expand your professional network to include people with whom you have actually worked. For in my experience, no amount of conversation or debate with somebody compares with the actual process of working with them on something real. And pairing provides the perfect opportunity to do this. Within half an hour of pairing with somebody I can have a fair understanding of their strengths and weaknesses as a developer. No amount of chit-chat over beer at networking events can give me that.
Like knowledge dissemination, a critical factor in achieving team cohesion and networking benefits from pairing is to rotate pairs. The less you rotate, the less benefit you are going to see.
A final, undoubted benefit of pairing is momentum. The pair tend to spur each other on. Is that big bowl of pasta that you had for lunch sending you into a mid-afternoon slump? There’s a good chance your partner’s going to be able to step in and drive until you snap out of it. Hit a wall trying to solve a particularly nasty problem? Maybe it’s time your partner took over and voiced some alternative approaches. Brain frazzled and going down rabbit-holes after too much coding? Let your partner step in and provide some perspective. Tempted to surf the web for a while? Not so much if there’s somebody sitting next to you. Pairing keeps you honest, focussed and productive.
Some Awful Truth(s)
All of these benefits are great, but let’s face it: many developers didn’t get into computers so that they could interact with people all day. I’d be the first to admit this is a problem, because building any non-trivial piece of software requires collaboration. Furthermore, I don’t think that we, as a profession, collaborate enough. Consequently, any practice that promotes collaboration and communication between developers should be encouraged.
The problem with full-time pair programming across an entire team is that it is very committing. Whilst in theory the benefits increase with the the amount of time that you spend doing it, the pluses have to be traded-off against both the obvious resourcing implications, and the less-obvious cost to engagement and motivation for those who struggle with having somebody in their face all day, every day.
Should we pair more? Probably. Should we pair full-time? I’m not sure if that’s a realistic goal.
Yet we seem to have become polarized on the topic: on one side we have an apathetic majority who are not interested in even giving pairing a go. On the other side we have a vocal minority who want everybody pairing, all the time. I think neither side is being particularly honest about their own limitations, or about the limitations of others.
Instead, I think the real challenge is be able to step back, make the best call for a particular circumstance, and then – most importantly – adjust as circumstances change.
If members of your team want to pair program, you should seriously consider their request. Developers are generally an introverted bunch – if they’re that keen on pairing that they’re willing to stomach the constant social interaction, that’s a sign in itself that there must be something in it. Furthermore, for those managers who are petrified of pair-programming because they envisage a drop-off in productivity, in my experience any such declines can be offset with decreased error rates, sustained productivity, increased knowledge dissemination amongst the team (which translates to a reduced lead-time for new team members to become productive), and improved team cohesion.
Conversely, if members of your team are reluctant to pair-program full-time, respect their concerns – especially if they’ve given pairing a go and decided it’s not for them. If you push them into doing it anyway, there’s a risk that you’ll see a drop-off in engagement and motivation that offsets any of the benefits that come with pairing.