Tuesday, 21 August 2012

A Case For Pair Programming

Quite some time ago I blogged about why Test Driven Development is so useful. Today I present a sister argument for Pair Programming.

In other industries predictability is often seen as a bad thing, but in the context of software delivery it's the Holy Grail. If a team repeatedly ships new features every day / week / month, without fuss, rollbacks, bugs or any other kind of hoo-hah then quite frankly that team rocks. What's more, if a team has predictable delivery they can self tune and deliver faster. It's much harder to tune a system with a high degree of variation. Show me a customer or manager who wouldn't delight in a team like that, and yet rarely will they put their hand in their pocket and pay for it when the proposed method is pair programming. Why?

What Is Pair Programming?
Before I go any further, let me explain what I mean by pair programming. Two humans, two keyboards and two mice, working on the same feature, at the same time on the same PC. Why two keyboards and two mice? because there's a natural reservation to grabbing the keyboard while someone else is typing on it. It feels rude. If you have your own keyboard there's no such reservation and you will contribute far more. I should also point out I intentionally wrote "humans" not developers. Pair programming shouldn't just be limited to programming. It covers anything required to get the story done, including front-end work, dev ops, sys admin and crazy (why would you buy it!!!) middleware packages. No special cases.

There are different strategies for how pairing should operate. A method that's often floated is that one developer writes code while the other thinks about the bigger picture. Another idea is pair-ping-pong, where one developer writes a unit test and the other makes it pass. I'm not keen on either approach. I find pairing works best when it's like a conversation, which each party taking turns listening  (watching) and speaking (typing), but with the option of interjecting at any point.

What Is Pair Rotation?
Another ingredient that's vital to successful pair programming is pair rotation, and again there are multiple approaches. Without pair rotation both developers stay on a story for it's duration. This has the advantage of minimal handover but also comes with some severe drawbacks. The same pair of developers will end up on consecutive stories as there will be no-one else free to pair with when the first story is complete. Skills and ideas will not cross-pollinate throughout the team. Developers will build up expertise in some areas of the code, while being unfamiliar with others. There will be no common code ownership.

To counter this, teams sometimes allocate a permanent story owner to each feature and rotate a second developer in on a regular (e.g. daily or half-daily) basis. This maintains some consistency for the duration of the story, but also improves communication throughout the team. There's a problem though. The pairing is unbalanced. The story owner, being "responsible" for, and more knowledgeable of the feature becomes the dominant force. The second developer is less likely to challenge the story owner, and more likely to disengage.

Our solution is to roll the story owner off onto another feature, and promote the second developer to story owner. Now the second developer has skin in the game. They know that they have to understand enough about this feature to lead it when the next handover occurs. They won't allow the story owner to cut corners, because in a short while it will be their feature and their mess. Cross-pollination is twice as rapid as before, so the code base will be more consistent and familiar to everyone. This solution does come at a price however - occasionally information acquired through conversations and not documented on the story card may be omitted from the handover, and since both developers can roll off onto new stories, it's possible for this information to be lost, resulting in bugs and rework. We've been running with this approach for some time, and even with the occasional mistake the payoff has been worth it.

So that's how I advocate doing pair programming, and now it's time to look at the benefits. I've briefly mentioned predictability, cross-pollination of skills and ideas, common code ownership and if you read between the lines improved code quality. I'll expand on those areas now.

Key Man Risk And Flow
The most obvious benefit of pair programming (with rotation), is removal of key man risk. In traditional development teams it's common for developers to become experts in one area of the code base. It's even seen as a good thing since because those developers are experts they will be able to deliver features more quickly. The problem is that these developers become indispensable "heroes", leading them to become over worked, stressed and unhappy. In the worst cases I've seen them become arrogant and destructive. Team members don't keep tabs on what each other are doing and it's common for unit testing to be skipped over and for the code to get ugly. I've often had to re-write large chunks of an application because of exactly this situation. A similar set of problems occur when a minority of team members have a niche skill such as a dedicated DBA or front-end developer. Effective pairing eradicates the issue of key man risk completely.

Closely related to key man risk, is flow. If only one team member is familiar with a particular part of the  code or has a critical skill not shared by others, then they become a bottleneck. Work will not flow steadily and predictably through the system. Instead it will begin to back up and take longer to deliver, again leading to the "hero" anti-pattern. Whenever a bottleneck goes on holiday the whole project can grind to a halt. Both situations incur extra management effort, and can lead to some truly ridiculous solutions being imposed, like parachuting in green "resources" to ensure velocity doesn't drop.

In contrast if every team member learns to work on every part of the system and develops all the required skills to at least a competent level, there will be no major bottlenecks and no key man risk. You will start to achieve the predictable delivery I mentioned in the opening paragraph. Initially pairings will be unbalanced due to one member having greater skill or domain knowledge, but this will self correct over time and even while the pairing is unbalanced, the weaker member will often have a positive influence. Server side developers may find themselves coaching front-end developers resulting in cleaner Javascript and drier HTML. Front-end developers might find themselves demonstrating how a little bit of CSS magic can negate the need for some server side code entirely.

Cross-Pollination Of Ideas
The next obvious advantage of pair programming is cross-pollination of ideas. When developers work in isolation pockets of code evolve in overly specialist ways (think duck-billed platypus), and the code base loses coherence. When developers pair program and rotate, the ideas are validated and reuse increases. Significant work and rework are avoided.

Inherent Discipline
A more subtle, but equally important benefit of pair programming is that it stops blame. When a single developer works on a story, if that story takes significantly longer than expected, it isn't clear whether it's because the developer was inadequate, or because the story was more complex than originally thought. Even if no one is pointing the finger, the developer will start to feel pressure, and this can result in corner cutting. If however a story is taking longer than expected, but half the team have rotated through the story then it's clear that the team underestimated the complexity of the story when it was first introduced. This combination of a no-blame culture and the incentivising of the second developer to prevent the story owner taking shortcuts ensures that test driven development is done properly, and therefore leads to higher quality, sustainable code.

Cross-Pollination Of Skills
My final argument for pair programming is cross-pollination of skills. I was a specialist Java developer, with basic HTML, CSS, Javascript and SQL. Now, thanks to pair programming I'm a generalised specialist, able to do all this and more to a high standard. Many companies appreciate the value of this for permanent employees but baulk at the suggestion for on the job training for contractors. They're cutting off their nose to spite their face. In a previous blog post I wrote about the power of intrinsic motivation (you will work for someone you hate, but die for someone you love). One of the ingredients for intrinsic motivation is mastery. Permanent and contract staff alike will be more motivated if they are acquiring valuable skills. I witnessed this on a project some years ago, where despite having no looming deadlines or pressure to deliver, contractors were regularly working until 8pm on a Friday night, purely because they were enjoying the project so much.

Code Reviews Aren't A Substitute
One counter argument that is raised against pair programming is that similar results can be achieved through code reviews. In practise they can't. The problem with a code review is that feedback is too late. The code has been written. The time has gone. The money has been spent. The review feels like a chore. The reviewer wants to get back to their own work, they won't fully appreciate the context of the problem the developer was trying to solve. The reviewer avoids pointing out minor issues because they don't want to appear petty. Any change that requires significant rework must bring an equivalent benefit. Pair programming doesn't suffer from any of these problems, because the review is done in real time, the mistakes have not been cemented and so the code can be improved with little cost.

Why Is Pair Programming So Rare?
So with all this in favour of pair programming why is it the hardest agile practise to get accepted? The reason is that most organisations are setup with administrative staff in a position of control instead of providing a supporting role. It's hard to put a dollar value on the benefits of pair programming, but it's very easy to put one on its cost. In Predictably Irrational, Dan Ariely shows that when there are two options available, and one is easy to evaluate but the other not, human beings overwhelmingly make decisions based solely on the option that is easy to evaluate. Since doubling the burn rate is obviously bad, but the benefits of pair programming are hard to quantify in units of time or money, it doesn't get a look in. And this is why so few teams ship new features every day / week / month, without fuss, rollbacks, bugs or any other kind of hoo-hah.

No comments:

Post a Comment