The Benefits of Pair Programming
When pair programming works, it works really well. Here’s why.
There are often dividing opinions about pair programming. Here is my experience pairing with other developers, from the great to the ugly.
Let me start off by saying I practice pair programming (also called pairing) like a religion. When I was a graduate, pair programming was my saviour when I did not know exactly how to break down a story or a piece of functionality. It was my saviour when I wanted to learn and upskill quickly. It was my saviour as I transitioned from being a university student, with no idea of what “good” code looks like, to a budding software developer.
Yet pair programming is often a practice that divides developers, engineers, and managers alike. Why is this?
A brief introduction to pair programming and its controversies
Pair programming is where two developers work together on the same programming/coding task while sitting next to each other, and most importantly of all, they work on one computer only. It is a widely used methodology in software development; according to Stack Overflow Insights 2018, pair programming is used by 28.4 percent of all respondents. Typically the pairing setup will include two sets of keyboards, two mice and either one screen or two screens which are mirrored.
Now you might be thinking, “This sounds like a waste of time, two developers doing the same thing?!” Indeed, programming has historically and stereotypically been a very lonely task. We see developers coding solo very often, and there is a lot of reluctance to actively code with another developer. This is because software development can be considered a “craft” — a mixture of mathematics, logic, and creative thinking — and so code can be quite personal to some, just like a piece of art.
Now, let us place ourselves in the shoes of a software manager or project manager (role titles will differ according to the company, but you understand what I mean). To the outside eye, it would seem as if there are two people working on the same task that traditionally has been done solo. This definitely does not look cost effective at all, and the economics simply don’t make sense (hence the controversy).
One time, a manager told my team that we will “absolutely do no pairing,” and if they saw two developers even looking at the same screen, there would be consequences. Personally, this left a very sour taste in my mouth, as it echoed a sentiment of anti-collaboration. Ironically, teamwork and collaboration skills are the most highly sought after, according to the JobCentre Plus’ survey of 4500 UK employers. So that’s the other side of the story.
Sure, two people working on the same task. But the benefits of pair programming justify it.
I have been in two scenarios where pairing went absolutely amazingly.
The first is when one person in the pair is a lot more experienced and willing to teach. This is typically called the novice-expert pairing. There are some great benefits with this pairing.
The obvious benefit is that there is the sharing of context and distribution of knowledge within the team. Around a year ago, I was in a project in the telecommunications industry. On the first day, I started pairing with the other developers, so from day one I was contributing towards delivery of work. This is significant given that I was ramped up within a week when, according to the StackOverflow Insights 2018, 44.7 percent of respondents said they expect a co-worker to take one to three months to get up to speed. I got to learn the acronyms and domain concepts that the stakeholders (both the business and telecommunications technicians and others) used because these were present in the code, and my pair would explain them all to me. This in turn increased my confidence in the code I was writing on a new codebase and also increased developer satisfaction. Zero time was spent floundering around trying to work out what the existing (and somewhat legacy) codebase did.
I am not alone in thinking this. Ninety-five percent of developers in a survey stated that they were more confident in their solutions when they paired. This is in contrast to some other projects I have been on where no one is willing to, or willing to make time, to share context, which leads to a downward spiral in self-confidence.
For similar reasons, pairing also is great for upskilling each other —after all, everyone has something to offer! If you have an Android developer and an iOS developer in the same team, they have the potential to upskill each other during pairing. Then, either of them can work on Android or iOS. Let that sink in for a moment — a completely cross-functional team can be very powerful. I was a part of this pair for some time, and we were able to share deep insights for different platforms. She learned how to make Android apps easily testable, and I learned how the UI in iOS apps work. You can imagine in a case where you have non-cross-functional teams; you may end up in a case where dependencies on certain people to do the work arise (leading to waiting time).
Most importantly, the code is of higher quality and produces less defects. In a study from 2000, Cockburn and Williams showed that when two people pair programmed, as opposed to solo programmed, there were 15 percent fewer defects, and this difference was statistically significant.
This is important because defects are often not considered when we talk about how long it takes to get the job done. Indeed, while the standard Definition of Done in Agile software development is centred around how can a story get to production and be of production quality (the two things are not the same), this concept is often forgotten. We tend to focus on how quickly stories are moving from the “Doing” or “In Development” column to the next column.
Defects are one of the seven wastes in Lean, and it is hard to truly evaluate the economic cost of defects because there are a number of non-obvious tasks that go into fixing defects. For example, the person fixing the defect may not be the one who worked on the corresponding story, meaning there is extra effort and time needed to understand the code (in a non-pairing scenario). Context is lost. Another example of a hidden cost of defects is that the functionality needs to be retested. Regardless, defects are most definitely rework and will delay a team in delivering good quality software.
Let’s talk about the second type of pairing combination which I find great enjoyment in: when the two people are at equal levels, both with some decent amount of experience. This is typically called the expert-expert pairing.
With the expert-expert format, you may get less net benefits (for instance, experts are already presumably experts, and therefore will produce higher quality code and less defects). However, in my experience this combination yields amazingly high developer satisfaction. Often I am looking for my solution to be challenged, and this sort of pairing provides exactly that, and the end result is a fusion of the best ideas from both of us.
You may have noticed that I did not mention the novice-novice pairing (for example, two graduates pairing), and it’s for a reason. Some advocates of pairing have argued that this pairing will allow the two developers to share perspectives from elsewhere (e.g. other tech stacks) and learn together. This can work in theory, but in reality I have often seen this result in two very disgruntled, confused and frustrated developers.
During a brief stint as a coach at a graduate training program, we paired graduates with other graduates. What resulted was many of them approaching me with fears that they were not learning how to write good code, but rather simply doing whatever works. Developer satisfaction went down. Confidence went down. Most importantly, after pairing, they still did not know what good looks like. This is one of the main reasons I personally prefer the novice-expert and expert-expert pairing over novice-novice.
To sum all of this up, pairing has a lot of benefits when done properly. However, I want to caveat that, without pairing, you can still achieve this sort of culture, but when pairing is a part of your team’s culture, it is almost guaranteed.
When pairing doesn’t go so well…
Make no mistake, I have also been in situations when pairing has not gone splendidly. Pairing techniques also need to be developed, just like any other skill.
So when is it not effective?
I have found pairing to be the most ineffective when you are in a novice-expert pairing, with the expert being disengaged and unwilling to share context and/or knowledge. You actually get none of the benefits mentioned previously.
Other common non-effective pairing situations I have either been through or observed:
- Novice-expert pairing, with the novice being disengaged and unwilling to learn. This is especially frustrating if you are willing to teach and want to share the knowledge, only to be met with a brick wall.
- Novice-expert pairing, with the expert driving the code all the time and not allowing the novice a chance to experiment and practice. This is an extremely frustrating experience especially if you want to learn, yet you encounter what is known as a “keyboard hog.” This is also known as “go make me a cup of tea while I finish this program” syndrome (which Matt Stephens and Doug Rosenberg spoke of in Extreme Programming Refactored: The Case Against XP).
- One developer of the pair is not open to differing opinions and shies away from a respectful technical debate. This is a tough one, because it means you need to accept that sometimes your solution may not be the best one or may be enhanced by ideas from someone else.
In such cases, the expert developer(s) might as well have been solo. Pairing demands both parties be equally invested, open, and focused for the benefits to be realised. It allows a team’s capabilities to grow and develop, but without willing, rigorous individuals, it will not work.
How do you mitigate these issues?
This may sound silly, but one way to mitigate these issues is by providing a comfortable working space which actually facilitates pairing. Pairing is a difficult skill to execute effectively already, and the challenges are even more pronounced if two people are working from only one keyboard, mouse, and screen. Very quickly one half of the pair may feel redundant, useless, and bored if they are not able to type frequently enough. It may also be very uncomfortable to actually work in these circumstances. (Back pain, anyone?) Again, this point may seem trivial, but on a recent project it took me a month to get an extra keyboard and mouse because of corporate red tape. Pairing, of course, did not work — we were not set up for success.
Another aspect to consider is a pragmatic approach to pairing. Perhaps not all tasks need to be done in a pairing style — this is a decision your team needs to make. Some development tasks are not complicated, and everyone in the team is capable of completing them (something simple such as changing the text or colour on a button). Be careful of the slippery slope — it is easy to foster a negative culture where people say everything can be done solo, and no knowledge is shared amongst others.
Also feedback, feedback, feedback. If pairing with someone isn’t working out, don’t let that turn you off pairing — give that person feedback and see if changes happen.
To pair or not to pair?
While I am a true believer in pairing, I also recognise it is not the best model for every single team. It would be unrealistic to say that pairing is the only way to achieve the outcomes mentioned before, and if working as solo developers but doing effective code reviews and share-backs are more effective for your team, then so be it! But if your team wants to try out pair programming to see if it changes your team for the better, then why not? Pair programming works magic when it is done well and your team genuinely wants to do pairing.
Remember, people over processes and tools.