Successfully Adopting Pair Programming
In 3.5 years as a consultant I spent more time talking (with clients) about pair programming than any other topic. In general, client developers had never properly paired and had no desire to do so. To make matters worse, the business predominantly thought two developers on one machine was a waste.
Despite the prejudices, usually by the time we left a client the business and developers had become pro-pairing.
Successfully adopting pair programming can be hard, but it's also entirely possible if you leverage the lessons I've learned.
This article assumes you have done some pairing and are looking to help your organization adopt pairing where it makes sense. The advice can be helpful for people in various roles; however, it is written mostly for developers or team leads looking to introduce pair programming to their teams.
This article makes no attempt to address whether you should or should not be pairing. There are benefits and drawbacks to pair programming (like most things), and I think there is already decent information available covering that topic. Discussing the pros and cons of pairing would take away from the focus of this article: If you already believe in pair programming, how can you successfully introduce it to your team?
In my experience, the single largest step towards successfully adopting pair programming is getting proper pairing stations. My preferred pairing configuration looks like what's described below; however, you'll likely need to customize it for your specific situation.
- Flat desks so that both people can sit comfortably next to each other. Nat Pryce has also had success with round tables. Desks that curve toward you usually don't provide comfortable working conditions for pairing, and should be avoided.
- The fastest development machine you can reasonably buy. If the pairing stations are better than the individual computers they are more likely to get used. Also, you only have to buy 1 per two people so you can afford to spend a fair bit more.
- A video card with dual DVI output. Splitters work, but not well. It's much better to have dual DVI out so you can get maximum resolution.
- Two 24" or two 30" monitors. Two large monitors are fantastic for cloning (or mirroring) your desktop, the result (when combined with dual keyboards and mice) is each pair member feeling like they have their own workstation.
- Two keyboards & two mice. Get both so those that like both can use both, but recognize that some team members may prefer to use only one of the keyboards and mice.
The idea is to create a working environment that is ideally better, but at least as comfortable as working on your own computer.
It's tough to get someone to leave their desk (and headphones) behind, but asking them to do so and work in less-optimal environment is just foolish. Instead, create an inviting pairing station that people will prefer over their personal desktops.
Getting a great pairing station is a large first step; however, it's also important to set up the pairing stations correctly. In the past I've had the most success with creating a pairing station image and using it to set up all additional pairing stations. It's also nice to have the pairing stations re-imaged on a weekly basis. Often developers will add a new tool or alias to a pairing station when they need it, but that tool or alias won’t make it on the other pairing stations for the rest of the team to use. I've found that re-imaging the stations regularly forces the team members to update the image instead of individual pairing stations one at a time.
What goes on the image depends very much on the team. In theory you might expect chaos when asking a team to agree on an editor, desktop layout, etc. In practice any team member worth their salary is going to want to work with optimal tools. Optimal can occasionally be subjective; however, there's usually a superior tool. In the cases where there isn't a clear winner, it's generally easy to select a standard a move forward. The result is really quite nice: an image with best of breed tools that ensures each team member will be highly effective at any pairing station.
Don't expect to get the image right the first time. That's okay. Creating the image is an iterative process that the team should be continuously improving.
I've been very successful with getting co-located, pairing space. Almost everyone has a conference room that they are willing to give up when you promise 20% efficiency gains (between pairing and co-location, a 20% gain is pretty easy to get). At DRW (my current employer) we tore down the cubes on my team and got straight desks. We gave up our 'personal' space and created a pairing area. If I want to work on my own, I can always take a laptop into a conference room.
I believe that without proper pairing stations you will fail even if you follow all the other advice in this article; however, several reviewers of the article disagree with me. What we do agree on is that: the most important thing is to remove any possible barriers to adoption. In my experience the largest barrier is giving people a comfortable working space, but as my reviewers point out, there are no rules that universally apply.
Focus on One Team-Member At a Time
I don't believe in forcing anyone to pair. Some people like pairing, some don't. However, you aren't going to make friends by forcing team-members to give pairing a shot.
I've had significantly more success by using a grass roots approach. In general I start by almost exclusively pairing with someone who isn't convinced but is open to the idea. It doesn't take long before they also prefer pairing to working alone. At that point I know I can move on to the next person who's open to the idea. I always go for the lowest hanging fruit and work towards to the person who's least open to pairing.
More often than not I never end up getting to the person who's least open to pairing. One of two things usually ends up happening before I reach them.
- They notice that the rest of the team is working significantly faster and ask if they can get in on the pairing also.
- They notice that the rest of the team is working significantly faster and they end up leaving. It's obvious to everyone that those who don't go along with the team have poorer performance. Generally these people see the writing on the wall and move on.
In my experience, 90% of the time the employees you want to retain end up preferring pairing. However, it's definitely worth considering how losing someone who isn't open to pairing will impact your project and the business. Sometimes it makes sense to move these team members to roles where they won't feel threatened or pressured. Other times it might make sense to let them move on.
Just to be clear, there are plenty of great developers who don't believe in pairing. I'd contend that it's very likely that the majority of them have never properly paired; however, even after pairing properly there will likely be a significant portion that will prefer to code on their own. I tend to classify those people as good, just not good for teams that are primarily composed of people who prefer to pair. Preferring pairing is not an indicator of talent; likewise, disliking pairing is not an indicator of a lack of talent.
Longer term I believe it’s a mistake to have opposing views on pairing within a single team. In my experience both sides feel like the opposing view is highly inefficient. As a result, otherwise rational and friendly team-members seem to continually battle over the topic and spend far too much time on arguing and assigning blame. I believe there is room in an organization for both views, just not within the same team. Part of successful adoption is being able to identify those that will never agree, and not wasting time on an impossible goal.
If you are working with someone who is open to pairing, but not yet convinced, it makes sense to pair with that person often or all the time. The first several pairing sessions are often an adjustment period and it's important to provide them with the best pairing situation possible. However, once someone has moved from experimenting to enjoying pairing it's often better to start pairing with different members of the team. In my experience it's best to pair with someone for a minimum of 1 day and a maximum of 2 days. Those guidelines are influenced by context; however, they've historically remained fairly constant for me.
There are conflicting views on what is the most effective length for pairing with one teammate. As I stated above, I generally spend at least a day with a pair, but never more than two. For other points of view I suggest looking up pair switching once per iteration and promiscuous pairing. Both are what I would consider extremes, but I also recognize that there are contexts where they are probably just the right idea. By switching pairs fairly often you'll gain at least two large benefits.
- People will have varying degrees expertise in tools (e.g. grep, IDEs), the domain, patterns, testing, and so on. It makes sense to work with whoever is an expert in the area that is required to implement your current feature.
- Working with different team-members will allow you to more easily balance the amount of time you spend being a learner or a mentor.
The benefits of pair switching lead to greater efficiency, which leads to even more adoption success.
Who Should Drive
People new to pairing always ask: don't you both end up typing at the same time? The short answer is no. If there are ever issues with someone typing too little or too much they can easily be addressed by Ping Pong Pair Programming.
Ping Pong Pair Programming (or Ping Pong Pairing) is where two people alternate writing tests and implementations. The more verbose name, Ping Pong Pair Test Driven Development, is probably more valid, but rather unruly. The workflow of the pair would go as such.
- Pair developer 1 writes a failing test
- Pair developer 2 makes the test pass by implementing only what's necessary.
- Pair developer 2 writes a failing test
- Pair developer 1 makes the test pass by implementing only what's necessary.
- Go back to step 1. Follow this loop for the entire pairing session.
When introducing pairing Ping Pong Pairing can be very effective; however, after the initial few days I find that 'who should be typing' is often determined by what role each member of the pair is playing.
Given almost any task, a pair generally has one member who knows more about the problem at hand than the other. In this case it generally makes sense for the less-informed pair member to do the driving. The mentor should switch from the mindset of "here's what I would do to deliver this feature" to "how can lead my pair to the correct solution to this problem". Instead of being a feature implementer, it's much more important to be a teacher when playing the mentor role. You know the saying: Give a man a fish and you feed him for a day. Teach a man to fish and you feed him for a lifetime.
Note: I’ve found the roles to be helpful during learning, adoption, and steady-state pairing. When learning and adopting pair programming, recognizing that you are the mentor and effectively transferring knowledge can build a great deal of confidence and trust with your pair. During steady-state pairing, playing the mentor role allows you to transfer knowledge while progressing towards feature completeness.
When playing the mentor role it's also a good opportunity to consider the bigger picture and your current path. You may think of a simpler way to solve the problem at hand. If I happen to think of a more effective way to solve the problem I ordinarily finish teaching my pair how to complete our task using the first approach (time-boxed if necessary), and then I quickly spike the other idea. If it turns out to be superior I ensure that my pair understands why we switched. If it turns out to be inferior, we can easily revert to the previous solution.
If there's a mentor, the other person must be a learner. As a learner you have only one task. Take control of the pairing station, discuss the problem until you understand it, and implement the most obvious solution to you. If your solution is suitable the mentor should be able to provide any necessary guidance. If your solution is inferior, it should be easy for the mentoring pair to discuss the limitations of your proposed solution and provide you with direction on how to improve your solution.
As a rule, the learner should do the majority of the driving.
Uninterested & Distracted Pair
Sometimes your pair is uninterested in the task at hand. It's never fun for either person when working with an uninterested pair. A benefit of pair programming is getting the best solution when two developers collaborate. Clearly, an uninterested developer is not collaborating, thus the solution is likely inferior. At a minimum, the solution is as good as it would have been and 1 person's time was completely wasted.
There are several reasons that a pair can be uninterested. However, addressing why a pair is uninterested is a people question that cannot be reasonably answered in a general manner.
Distracted pair, as the name implies, is a pair who is easily distracted by their surroundings. Distracted pairs tend to spend less time typing, because they are always busy helping everyone around them. Distracted pairs are not useless; in fact they generally contribute significantly to the code the pair is working on. However, distracted pairs are rarely contributing at their full potential because they are often attempting to solve the problems of multiple pairs at the same time. Some distracted pairs can also spend too much time checking email and doing other ancillary tasks.
Joel Spolsky believes that open space working areas are fun but not productive. While I don't agree with him, I can see how a few distracted pairs could easily make a manager draw that conclusion.
I've been a distracted pair. I've also worked with several distracted pairs. I believe that it happens to all of us from time to time. In the past I've seen distracted pairs managed by creating rules. For example, a "no personal laptops in the development room" rule existed on a previous project. This rule can help address the problem, but it creates other problems.
The largest issue with uninterested and distracted pairs is that they aren't fully participating in pair programming, thus negating several of the productivity gains. If you find yourself stuck with an uninterested or distracted pair there are a few things that can help.
My preferred method of handling a distracted pair is to practice Ping Pong Pairing. Ping Pong Pairing forces both pairs to be paying attention at level one. Another nice attribute of this suggestion is that it doesn't require any additional rules that could have problematic side effects. Ping Pong Pair programming helps turn an uninterested pair into a contributing pair; however, often their level of contribution isn't up to their full potential. I've found that when dealing with an uninterested pair it's actually more beneficial to feign confusion.
Feigning confusion can be boring, really boring. You generally have a grasp on what needs to be done. More often than not, you also have the solution in your head. You can implement this solution on your own and bring the uninterested pair along for the ride; unfortunately, in my experience that's exactly what happens. But, simply taking the uninterested pair along for the ride isn't the best long term solution. That pair may someday be asked to improve the existing solution. If they can't, because they weren't paying attention, you may be taken away from your task. Worse, you may be off the team and the context of the code is permanently lost.
So, feigning confusion is boring, but it is also in the best interest of the team. Instead of implementing the solution, ask your pair: How we are going to get this done? Don't accept their first answer. Their first answer is likely going to be fast, but incredibly ugly. Provide your own input, but don't let on that you have a solution. Instead, stick to asking questions. Chances are, you are going to understand their solution. It doesn't matter if you understand their solution, pretend that you don't. Force the uninterested pair to write the first 3 tests and implement the code that causes the tests to pass. At that point, take over and write a test, but force them to implement the solution. Then slowly proceed into Ping Pong Pair programming, but don't jump straight into it. Instead, force the uninterested pair to do about 65% of the coding. It shouldn't take long for the uninterested pair to be a fully contributing pair, which benefits everyone.
Large gaps in talent can turn a teammate into nothing more than a spellchecker. I've seen this repeatedly throughout the years; however, it happened recently to me. I took a new job and on my 2nd day of work I paired with one of the most senior guys in the company on implementing in Java a library he had previously written for .net. I was new to the domain. I had never really done Java professionally. I hadn't ever seen the .net version of the library. I had never used the messaging system the library collaborated with. I had never used IntelliJ for coding Java. And so on.
I was worthless to my pair. The task was somewhat time sensitive, and the information gap between us was so large that I was reduced to silence except when pointing out a spelling mistake. I got to drive some also, which consisted of my pair telling me what to type.
While I generally prefer pairing, if a teammate is providing nothing more than spelling suggestions it is probably not the best use of his time. Furthermore, when an experienced teammate is required to slow down to explain things the task is going to take longer to complete. When the experience gap can be bridged this is generally the most efficient course of action. However, when the experience gap is too large to reasonably bridge and successfully deliver, the pair should split.
When Not to Pair
There are several situations when it makes sense not to pair, including when one pair member is reduced to a spellchecker. Other common situations when it makes more sense to work on your own include:
- When reading about a library that might help later on
- Spiking a complex solution or debugging a tricky error with someone that has an experience gap. In general pairing is not ideally suited for the combination of exploration and bridging an experience gap.
It's important to remember that these situations are not optimal opportunities for pair programming. That doesn't mean you should never pair while doing them; however, if you pair on these activities you should recognize that one pair member might not be interested or able to provide value. One quick way to slow pair programming adoption is to put someone in a spot where they stop providing value.
Not every task requires a pair; however, the number of tasks that require pairing is a lot higher than the number of tasks that don't.
When reviewing this article Dan North pointed out: Perhaps it's not the number of tasks, it's the kind of task. Any development activity on the mainline of delivery (writing code, writing tests, build engineering) tend to be better quality when they are paired. For non-mainline tasks like spiking, research, admin chores, there is a diminishing return - so it's often better not to.
Core Pairing Hours
On average, if you determine that pairing isn't best suited for your current problem it makes sense to split immediately; however, I've had a lot of success with defining what hours of the day you are expected to be available for pairing (core pairing hours). Typically the core pairing hours are between 60% and 70% of your total work day. For example, if you work 8am-5pm, core pairing hours might be from 10am-4pm.
During core pairing hours you aren't required to pair (you should never be 'required' to pair). But, you should be available to pair. If you are doing an activity that is better done on your own, then don't pair. However, if you aren't currently pairing but are doing a task that is suited to pairing you should look for a pair or make yourself available to pair with someone else doing a task suited to pairing. It's also helpful (when possible) to put off activities that are better done solo until outside core pairing hours. For example, if a medium priority bug is assigned to you at 2pm and your pair knows nothing about the library that the bug exists in, it probably makes sense to wait until 4pm to take a look at the bug.
Core pairing hours are also nice because they allow some flexibility for working hours.
The number one objection to pairing is that people "need their own time" and aren't "able to pair for 8 hours a day". This objection is always funny to me because I don't think anyone should have to pair for 8 hours a day and I think everyone is entitled to their own time. I've found 70% of my time to be my preferred amount of time for pairing. I have some friends that prefer 60% and other friends that prefer 95%. I'm not sure who's on the right track, but either way no one is advocating 100%. Especially during the adoption phase it's very important to pair when you find it beneficial and split when you don't.
The Simplest Thing That Could Possibly Work
Do the simplest thing that could possibly work is a phrase held dearly to most agile developers, but it's not always easy advice to follow. If you do something too simple you can be criticized for being short-sighted. However, if you do something that is overly complex you'll be criticized for wasting your time and the time of whoever needs to maintain your solution. However, pair programming can help give you the confidence that your solution is simple yet robust enough to work.
When pairing, have the resolve to stick with the simplest thing that can possibly work. If you are pairing, chances are that you are wisely creating an elegant solution that will stand-up to average usage. By sticking with the simpler solution you should be able to create features faster and spend less time maintaining existing features. This efficiency boost should help drive home the idea that adopting pair programming is a good idea.
Mandate Code Review
If you want to improve the quality of the code you should have it reviewed by a team member. In fact, some laws (SOX, HIPPA) require all production code to be reviewed. If you're looking to introduce pair programming, but are smart enough to recognize that mandating pair programming is probably going to fail, you could mandate code review (for all production code) instead. To satisfy the code review requirement you could allow traditional code reviews or pairing. The primary difference between pairing and code review is that one is a critique, and has the connotations of ownership and defense, while the other is collaborative. Having your code reviewed is almost always a painful process, and it usually doesn't take long before people opt for pairing instead.
Mandating anything is always a risky move, and I would use this idea as a last resort.
Being "allowed" to pair isn't success. Success is when the team enjoys pairing and they are more productive because of it. If you approach adoption from that point of view you'll have a much greater chance of success. Therefore, when applying the ideas above, try to implement them in a way that focuses on team building and efficiency.
It's interesting to see how some of our practices at Resolver Systems have, after a little experimentation, converged with some of the things you talk about, such as frequency of switching - we all switch pairs every day, a move we were initially sceptical about. We anticipated that it would be too rapid, and would involve too much task switching and getting up to speed on new things every day, but it has actually turned out to be our favoured way of working.
Since we're only a small company, and we're all into pairing, it means we don't need dedicated 'pairing stations' - each of our desks is set up for pairing. We generally just work at whoever's desk is closest. We each choose our own IDE, and have quite a menagerie of them in-house, so generally everyone will also maintain an install of some generic environment which their pair can request to use if they want to. Formerly the lightweight but surprisingly powerful TextPad was a common choice for this, but nowadays we've pretty much got everyone graduated to Vi or somesuch.
A couple of our guys write a script for 'Vi' to toggle between two configurations, so we can toss the keyboard back and forth and still each use our own preferred Vi settings and scripts, etc. Obviously enough though, under such conditions, our settings tend to converge somewhat, as we all steal each other's best ideas.
Like testing, I'm amazed at how many incidental unexpected benefits come out of the pairing activity. Obsoleting code reviews is such a great thing, since it was a dull, life-sapping activity. Also I find that the guilt and blame surrounding ghastly mistakes (slippage or bad design or whatever) are eliminated, because people truly understand how the problems occurred - they were right there shoulder-to-shoulder with you when it happened. All equally culpable, hence forgiving and 'in it together'.
A question on Pair Switching
Great article! I get really inspired to try to introduce this concept in my current shop. Something that bugs me after reading your article is your section on pair switching. I was hoping that you could clarify this a bit - so I have the whole argument arsenal ready when selling the concept to my client :-)
In the my current project we work with SCRUM (or a version of anyway...) and all tasks/requirements are written on stickers put up on the infamous wall. We have a rule that if a requirement is estimated to more than 16h it should be split up into several requirements, hence no task is estimated to more than 16h. But the tasks belong to problem domains and developers tend to become domain experts by implementing all tasks for a domain.
My question, or concern, on pair switching is how you weave this work together with the requirements in your projects? Are you making sure that no task is longer than 8h to enable daily pair switching? Or is one of the developers always working with the whole domain and other partners switch into this domain on a daily basis? Or do you just don't care and just develop as much as you can on one day and then the next pair picks up the work where you left off?
I would very much appreciate if you, or someone else in this forum, could cast some light on how this could be done.
Re: A question on Pair Switching
Joakim Holm has a fun and interesting post on pair switching at jockeholm.wordpress.com/2008/05/30/parprogramme....
It's in Swedish but he refers to an English paper about "promiscuous pairing":
Joakim Holm will give a talk on pair programming and collaboration in the method track I host at Developer Summit, April 15-17. www.developersummit.se/
Re: A question on Pair Switching
Re: A question on Pair Switching
Sorry it took me a few days to get back to you.
I'd handle this in two ways. Firstly, yes, it's much easier to pair switch on a regular basis if the stories are small enough to get done in a few days. If you have to carry a week's worth of context, it's tough to get momentum on delivering a story.
If you can't break the stories down for some reason (try again! =) you can also have 'story owners' who are never away from the story for more than 1 day while it's under development. For example a story owner may be on the team that starts the card and work on it for the first 2 days, then work on something else for a day, then return to the card for another 2 days. A story owner can repeat that process until the card is done. That way, at least one person on the story has context for most of the life of the development on that card.
Thank for the comment and the question.
ping pong pairing
Roy Rapoport Aug 28, 2014