This page describes my approach and results (both positive, and negative) of introducing pair programming into my organization. I thought it might be useful to share these experiences with the community at large. -- MichaelKirby '''Basic Approach''' My basic approach is to slowly work through my team and use PairProgramming in a mentor relationship prior to having other individuals use the technique. Further, I intend to pair first with my more senior people. Not the least of which is because it will be easier on me (allowing me to discover my own flaws and issues in a more relaxed environment). But this technique also allows me to build buy-in from my opinion leaders in the group - the very people whose support is required if I'm to change anything in the group. '''Pairing Experience''' '''2002/10/05:''' The first pairing I did was truly amazing. The most difficult thing in our way was the completely different toolset used by the individual. It seemed that although he was a gifted programmer, he had not yet taken the time to optimize his environment. We spent the first day or so making things "hum". Debugger ran fast (he previously never used one all that much), we moved over to snapshot views (if you have ever used ClearCase, you would know why this is important). During the beginning of the pair, we traded a lot of "techniques" back and forth. There was a lot of expert-to-expert sharing going on. As we got into the technical detail, the PilotCoPilot relationship really began to demonstrate its usefulness. Overall, we wrote about 1500 lines of code in 4 days, with only 2 significant defects found since it was released. '''2002/10/20:''' The second pairing didn't work out as well. This individual was an expert as well, but I found her to be much more argumentative than the original person. It took me a couple of days before I finally understood the issues. The first issue had to do with the physical arrangements. There simply wasn't enough room in her cube. She uses a split keyboard, and it's difficult to share one of those. But the second issue was more difficult to pin down. She doesn't practice ActiveListening techniques (perhaps she practices AggressiveListening). That is, when she doesn't understand something, her immediate reaction is to say, "it won't work", rather than to say, "I don't understand". I also think this second pairing was much more difficult because of the complexity of the code we were dealing with. This is an area of the software that had been developed by a more junior individual, and showed much of the "strain" of that type of development. It would be quite reasonable to have a method set a number of class variables, and then call a sub-function that used the variables. Often, there would be several layers of state to wade through. Further, we were on a tight schedule to get as much "working" before the end of the release as possible. Perhaps there is a sub-pattern here that is worth exploring. PairAchievableGoals otherwise, the pair spins just as much as an individual might (maybe even more). '''2002/10/29''' The third pairing was with one of our most senior folks. Next to 1 or 2 others, he has probably written more code than anyone else on the team. It was my first experience where I really had to "work" to keep up. We spent about 7 or so total hours pairing (14 effort hours), and at the end, both of us agreed that we completed something that normally would have taken either of us 3 or 4 days to complete. It was clear that at the beginning he was not nearly as bought in as my first two pairings (or at least they humored me more). By the end, though I think he though the exercise was very worthwhile. I now have 3 people "certified" for pairing. One of them has come back to me asking me to pair with him again (person #1). '''2002/11/02''' I've started pairing with the more junior person now. It is interested to see how the dynamics of the pair are quite a bit different then my other pairings. As we started, it was clear that the other person didn't have a lot of confidence in understanding the current task. But she would use her solo time to review the code and understand what was going on. By the time we got to the end of about hour 3 she was starting to be much more involved. I think there is a key lesson learned here. Preparation is important for the pair to be successful if one of the members of the pair lacks confidence or experience. I had to continually restrain myself from reaching over and hitting "shortcuts" on the keyboard every time she did something in an inefficient way. (No! control-shift-N...Don't use the mouse...Right Click!! Right Click now!! Move the mouse up..up..down...left..left...now click!!!) Instead, I tried to let her do it at least once the inefficient way, and then ask her if she wants to see a better way to do it. ( at least that is what I tried to do most of the time...Sometimes I might have slipped back to my old behavior). The task we are working on is different then the others as well. Previously all the other pairs worked on solving individual problems. This pair is actually working on developing unit tests cases for some nasty code we want to fix. The experience is definitely different with the unit tests. I think had I been in an expert-expert pairing we would have been bored to tears. '''2002/11/05''' Continuing with the junior person I have begun to see flaws in my Pair Programming Personality. It is quite amusing. My office mate even commented that he doesn't see me giving up the keyboard very much. I now make a deliberate attempt to relinquish the keyboard to allow my junior partner a chance. I have found 2 major issues so far with my performance. 1 I seem to get very very irritated when the person doesn't use the most efficient way possible in the tool to do something. Much more so then I would have thought. Occasionally as the person is using the mouse to accomplish something that a single key stroke would accomplish, I will reach across the keyboard and hit the magic key. 2 As I get more experience with pair programming, I notice that the flow of the pair ebbs and flows from the more abstract, to the more concrete and back. I have found that junior folks do poorly when driving during a more abstract period. For example, changing the class structure to adopt a new pattern. When we get into raw algorithmic work, they do fine. By planning ahead a little (thinking ahead a little), I find I can make sure that I am at the keyboard during critical times, and I relinquish the keyboard when we hit the more concrete work. This seems to work fairly well. '''2002/11/13''' We had two interesting results today. Two of my senior folks paired together to work on a problem that one of them had already been working on for a couple of days. What was interesting about this was that both felt the pairing wasn't as effective as it could have been. In this case the individual working on the problem had already done the debug and picked a strategy for solving it. The other person wasn't really in a position to change the direction. I think the rule is that when 2 senior folks are pairing they should both start from the same place. Having one have a significant head start makes it difficult for the other to "catch up." The second pairing was myself and a more junior person. Ironically this also was a case of pairing to solve a problem that had been under investigation for a week. But in this case, the more junior person had reached an impasse in finding a solution. Initially the pair started out very similar to the first case. I was deliberately slowing the junior person down (who was exploding with information). After a while though, we converged and the "pair synergy" began to take hold. Here the rule appears to be that it is okay to have a senior person pair with a junior person who has previously done work on a problem, but it is most effective after the junior person has hit a wall. '''2002/11/18''' I've been pairing on a really tricky code refactoring for a couple of days now. This is probably the longest and most difficult problem I have tried to solve with pair programming. And of course, never being one to turn down change, I am also choosing this as the moment to introduce TestDrivenDevelopment. In our case, we have a section of code with about 12 open problems. It is pretty bad code, and its main detriment is that it has a ton of state. So it becomes very difficult to fix bugs because we keep hitting the WhackAMole problem. So we decided that the approach should be to write a set of tests to make sure we understand the existing behavior, and then factor the code out into separate modules (i.e. the Strategy Pattern). We are about 1/2 the way through it, and it seems to be working. The pair seems to be running smoothly, although I suppose I should give up the keyboard more often than I do. My partner even made the comment that she doesn't mind me driving as much as she used too, because being navigator gives her time to think. The weird thing, is that we hit most of our problems in the test cases, not the code itself. Because this is a refactoring, it is very difficult to write the tests first, and then refactor into it. We find ourselves doing the mechanical refactoring, and then writing test cases against what we just refactored (even before it compiles). '''2002/11/30''' We just completed the task. It is astounding how much work the test driven development was. Particularly when refactoring existing code. In this particular case, not only did we have the complexity of the existing code, but also the complexity of the test cases as well. Pair programming was definitely several times more productive then either of us along, simply because by maintaining the focus, and having 2 heads to store the algorithm in, we were able to keep things roughly straight. The TDD part of the experiment was interesting too. After the first week, it wasn't clear we were getting any bang for the buck, but at the very end it really kicked in and saved us. This particularly part of the code is famous for its wack-a-mole like problems. While refactoring, the test cases kept us aware of any introduced or discovered inconsistencies. Another one of my pairs completed an assignment this week as well. They seemed to work fairly well, although my casual observations were that one of the individuals suffers from the ProfessionalDriver syndrome. I tried to encourage more sharing, but it didn't seem to occur. I had another individual express concern that pairing with some individuals was not going to be productive. In this particular case it would have been an expert-expert pairing. The concern seems to be that one of the individuals tends to dominate the pair. While I can understand the concern, I don't want to turn pair programming into a popularity contest either. '''Ongoing Experience''' As I got more experience in pair programming, I have stopped recording individual sessions. I will occasionally come back here and post an update regarding the "how's it going". 2003/07/27 - It turns out that pair programming is actually quite hard to keep going on its own. I find that I am able to pair with individuals at will, and that I have several others that do it quite frequently. But most of my team seems to prefer solitary confinement, even if it is at a demonstratable reduced level of productivity. I suspect this has something to do with the unusually large number of introverts that exist in the software field. Has anyone else seen this? Some other observations are that even when working in pairs, I find that individuals will only perform at a level roughly equally to the union of the two developers. In other words, two mediocre developers will generally be mediocre. This seems self-evident, but it has some unusual side effects that people may not consider. For example, two people who generally write sloppy code will write sloppy code as a pair. Two individuals who can't abstract will pair program and create monstrous classes (bigger even, then either could do alone). In other words, pair programming creates a magnifying effect on people. *Their best traits are strengthened, as are their worst traits*. '''Next Steps:''' - Develop some rules for how to assign pairs to work. '''Lessons Learned (so far)''' * If you feel as though the pairing isn't going well, it probably isn't. Talk to the person about it, and try to "debug" it right away. * Make sure that physical facilities (obvious stuff like office, keyboard, etc) are in alignment, and acceptable. * Make sure that computing resources are adequate for the pair (i.e., the right editor, compiler, debugging aids, etc.). * Make sure the pairing session has a defined end. I find it much more satisfying if we can set the goal for the pairing session to be "fix the bug", "Write these unit test cases", etc. Even if you don't finish, you feel the pressure to get back together again to finish it up. * If you are going to be the junior partner in a pair (even if you are very experienced), preparation helps tremendously. Read up on the code that we are reviewing, or the technology to be used if you are not previously familiar with it. * Use the ebb and flow of the session (more abstract to less abstract) to serve as an opportunity to change driver between a more senior person and a more junior person. * Start senior folks off at the same place (don't pair late). It is okay to pair late with junior folks if the junior person originally worked on the problem and hit a dead end. * don't expect pairing two mediocre individuals will create great code. Bad programmers create bad programs even in pairs. '''Breaking the Pair''' One other lesson learned that was interesting, was that when pairing two people where neither party understood a technology or a problem well enough to immediately start work on it, it was more efficient to break the pair and allow each individual to study the technology/solution/... on their own, and then reconstitute the pair in a couple of hours. Trying to learn how JDOM works together is not very efficient. We just need to remember to bring the pair back together :-) '''Ongoing Questions (eventually with answers)''' '''Q:''' We currently do formal inspections of all code. One immediate question is whether, if I start to institute PairProgramming, I am going to find that my inspections process no longer pays for itself. In the first case, where we produced 1500 lines of code, we found 4 minor defects, and 1 major defect and 1 issue (someone didn't like the way we had designed it). That is a pretty low defect density for 1500 lines of new code. (By the way, the lines of code numbers use a physical lines counting rule, not logical). '''A:''' The obvious answer to this is set up an experiment and use data to make a decision. In PairProgrammingVsInspections I will try to design the experiment. '''Q:''' Interruptions - I am constantly amazed at how, while I'm deep in thought with another person sitting next to me, a third person can just come in and start talking, as if I had been waiting for this all my life. I must somehow recondition my team to recognize that when pair programming is "in use", the door is "closed". '''Q:''' Headaches - Does everyone else get headaches when they pair for 6 hours in a day? '''Q:''' Popularity - There is a risk that individuals will turn pair programming into a popularity contest, rather then selecting individuals that are best suited for the job. My gut tells me that this is a bad thing, and that I should resist it. Has anyone else out there seen a similar type of situation? How have you handled it? ---- ''Comments?'' Excellent! Please continue this. Regarding interruptions: Can you literally close the door to the office? If not, you might want to print out signs saying, "GENIUSES AT WORK - PLEASE DO NOT DISTURB" and explain to folks that, when these are posted outside an office, pair programming is occurring within and please don't disturb it. -- BrentNewhall ''It sounds a little arrogant, but the idea is not bad. I was thinking of handing out something that people could hang on the back of their chairs as a "do not disturb" sign. Right now my plan is to gain more acceptance of pair programming as a desired way of doing things, and then treat the interruptions as a "problem". If I try to make interruptions an issue before I gain the concurrence of my team, I am not likely to succeed. -- MichaelKirby'' Good points. It may take awhile for people to get used to the idea that pair programming should not be disturbed, though that may require a certain amount of explicit warnings. In some environments, people will interrupt practically anything as a matter of culture. Regarding the sign, I'm assuming that co-workers will understand that "GENIUSES AT WORK" is meant to be tongue-in-cheek. One could substitute "PAIR PROGRAMMING IN PROGRESS" if that's more appropriate for the environment. -- BrentNewhall Many years ago, I was mentoring a subordinate using something like pair programming. She needed more experience coding assembler and I was watching over her shoulder. I also had lots of trouble keeping my hands off the keyboard "to show her the right way". Eventually, I told her to slap my hands if I ever took the keyboard when she didn't want to give it up. It was a good lesson for me. :-) -- ShalomReich Re: Headaches... PairProgramming is hard work, don't ever let anyone tell you it isn't. The effort of keeping two minds synchronized and focussed on the same problem can be very stressful. We noticed that as soon as we started PairProgramming we were all a lot more tired at the end of the day and positively exhausted by the end of the week. We had to set up some time (about an hour) every day for developers to have some "alone time" so that they didn't get too tired from all the pairing. Also try switching pairs more often. You may find this helps (with the fatigue) or that it is just frustrating - we have had mixed results. ---- CategoryPairProgramming