Pair Programming is Overrated
It's past midnight, and I'm drinking coffee with gingerbread cookies. And I'm thinking, "it's time to write at least one real article for this website." After all, that was the reason it was created.
This text is going to be about pair programming, which is one of popular Agile development practices. Agile got a lot of publicity in the last couple of years. There are books, articles, seminars and a lot of general hype. There are also a few people who publicly claim that it's a copout for wimps who can't bear the weight a real development process. Very few of the the things I've read about Agile were balanced and reflected my own experiences. People either try to sell it too hard, or seem like they haven't ever considered let alone tried it.
Pair programming is probably the weirdest Agile practice. Two people use a single computer to write code. In it's pure form, pair programming is done on the day-to-day basis, for all the code and for all developers in the company. It's definitely not how-didn't-I-think-of-this-earlier kind of idea. But that's not important. The question is, does it really work?
The main benefits of pair programming that often get mentioned are:
1. It keeps employees concentrated on their job. You can't slack off when there is another person counting on you.
2. It allows people to learn from one another. If you pair with someone who knows a system, you will get to know it too.
3. It reduces the number of defects. Kind of like constant code review.
The first one is a really weird claim. If you need constant supervision to do your job, maybe you should try doing something else, something that engages you more? Personally, I didn't find peer programming help me concentrate. On the contrary, it multiplied the number of distractions two-fold, since every time my fellow programmer had to stop coding, I had to stop and vise versa. He got an urgent call? I can't work on the code. I want to get a cup of coffee? He has to stop working. It's annoying and a bit invasive.
Pairing prevents voluntary distractions, like checking personal email or Facebook, but the same social dynamics it stops you from doing research. No one wants to sit and wait while the other guy digs through 10 articles found online. So you have to move research outside of coding session. It might seem like a small thing, but doing so can be really harmful in the long run. When you face with a problem and can't research solutions, you are tempted to use something "easy" and "temporary." At the end of the day most people wouldn't even remember what shortcuts they took. (Even if those are somehow bookmarked, the motivation to look into doing same things the right way is significantly weaker by that time.)
The same goes for coding experiments or radical refactoring. Paired programming is stacked in favor of very straightforward coding process, and it adds significant inertia to it. Which might be all right for someone who tries to set up a kind of "software factory," but it's not clear where learning and getting deeper understanding of technologies comes in.
This brings me to the second point. Do people learn from one another when paired? It's a trick question, since no one said what kind of knowledge we're speaking If you work with some really shitty software and have someone who already worked with it, that person can teach you how to navigate the clutter. That's where learn-by-pairing idea really works. Not so much for new skills or methodologies. Because remember: paired programming is a technique for writing (production) code. And someone has to drive. As in operate the computer. If you start writing Lisp code with someone who has never even heard of the language, that's not going to be very educative. And if you try to direct that person to write Lisp code under you careful guidance, it will likely to be a very slow and ultimately pointless process.
Also, let's not forget that you don't really need a special methodology to communicate with other developers. Asking questions, discussing things, mentoring, doing code reviews - none of these things is a prerogative of paired programming. Of course, a lot of companies have broken environment that discourages communication. In such companies doing paired programming is a huge step forward. But that's kind of like advertising oatmeal by saying that it tastes better than cardboard. You need a better things to compare to.
Okay, to the last point: defect reduction. There are two general ways to reduce the number of defects in your code: prevention and detection. Example of the former would be when your pair asks WTF your code is doing, so you rewrite it and remove a latent bug. Example of the latter would be when your pair notices that you forgot about integer overflow, you correct it and thus remove the bug. Does this happen? Sure. Does this happen so often as to make a huge difference in code quality? I really don't think so. Many reasons why. To start with, catching a bug while watching someone write code isn't that easy. To a some extent, you cease to be a mere observer, and become a part of the process. This lulls your critical side. Another issue is that saying "WTF is this code" (even if phrased properly) is not easy and doesn't always yield the desired results. Yet another issues is the inconvenient truth: a pair of developers with one computer aren't likely to write code much faster than a single developer. If you divide your development time by two, there is a lot of things you could do with the other half of the time to improve code quality. So don't compare one hour of pair programming with one hour of typical programming; compare it with an hour of programming, plus thirty minutes of code review, plus another thirty minutes of re-factoring.
We just wen over the benefits list. Now to my own list, a list of negatives I didn't already mention. It isn't meant to show that pair programming is pure evil, but I do want people to think about the undesired effects it brings into development.
- Collective coding dulls the sense of ownership and responsibility for the software written. Both blame and fame get divided evenly between the two programmers, regardless of individual input, so people aren't as motivated to do something "extra".
- It's harder to track individual performance. If pairs aren't systematically mixed around, and if the company doesn't have a working mechanism to collect and do something about peer feedback, it can put bad developers in a much more comfortable positions than they would be otherwise.
- The success of pairing is highly dependent on personalities, backgrounds and agendas of the developers involved.
- If there is some disagreement over certain design questions, pairing is likely to result in design by committee (of two). You'll get half-assed consensus solutions lacking clear vision.
Pretty much all of these come into play the moment you get paired with someone both stubborn and incompetent. Even if you don't, these effects take place anyway, but in a milder, more subtle form. Again, I don't want to say "wow, pair programming is evil, don't ever do it". It has its uses. It can help people dealing with stressful assignments by sharing the burden. It can lend more credibility to developer's claims when they say something cannot be done in estimated time. It can familiarize people with each others' coding styles. But to use it as a preferred practice for writing all the code? I doubt that's a good idea.