Practical Remote Pair Programming

By Adrian Bolboacă
    What do you get with a Packt Subscription?

  • Instant access to this title and 7,500+ eBooks & Videos
  • Constantly updated with 100+ new titles each month
  • Breadth and depth in over 1,000+ technologies
  1. Free Chapter
    Chapter 1: Pair Programming and Its Necessity
About this book

Remote pair programming takes pair programming practices to the next level by allowing you and your team members to work effectively in distributed teams. This helps ensure that you continuously improve code quality, share equal ownership of the code, facilitate knowledge sharing, and reduce bugs in your code. If you want to adopt remote pair programming within your development team, this book is for you.

Practical Remote Pair Programming takes you through various techniques and best practices for working with the wide variety of tools available for remote pair programming. You'll understand the significance of pair programming and how it can help improve communication within your team. As you advance, you’ll get to grips with different remote pair programming strategies and find out how to choose the most suitable style for your team and organization. The book will take you through the process of setting up video and audio tools, screen sharing tools, and the integrated development environment (IDE) for your remote pair programming setup. You'll also be able to enhance your remote pair programming experience with source control and remote access tools.

By the end of this book, you'll have the confidence to drive the change of embracing remote pair programming in your organization and guide your peers to improve productivity while working remotely.

Publication date:
March 2021


Chapter 1: Pair Programming and Its Necessity

Pair programming can be easy to use when you are focusing on building software that is of high quality. You, as a programmer, can pair with other programmers to find quicker solutions to your problems and get better results. Furthermore, you can pair with other colleagues: testers, analysts, (dev)ops, security, and so on.

Pair programming in itself is simple: you have a driver who writes the code and a navigator who oversees the code. The two are roles that can change slower or faster, depending on your context. We will learn about them in more detail as this book progresses.

You can use pair programming in many moments. Typically, we pair program naturally when we are stuck and ask for a colleague's help. Also, we can schedule pairing sessions as a regular activity. Some like to pair daily, or just a few times per week. It's a matter of context and where it helps you get better results.

Usually, you pair program in the office, at your desk, or at your colleague's desk. You can take your laptop(s) and pair in a meeting room on a big screen, or on a terrace when the weather's nice. Or, you can remote pair program by using specific tools to pair with people wherever in the world, as long as they have good internet.

Continuous learning, improved quality, fewer defects, managing complex problems, and solving specific problems faster are just a few reasons to use pair programming. Because programmers deal with a mass of knowledge, wrapping your head around all the essential details with another colleague helps your endeavor with speed and quality.

In this chapter, we will cover the following topics:

  • The history of pair programming
  • Elucidating problems in pairs
  • Sharpening knowledge with collaboration
  • Gaining wisdom
  • Managing complexities in complex domains
  • Comfort for the future you
  • Programming with your CEO
  • How does pair programming work?

The history of pair programming

Pair programming has been around for a long time in the history of software development, even from the early days, when programming meant plugging in some wires into a control dashboard or inserting punch cards into a reader in order to compile your program.

It's just that people who used to program back in the day didn't call it pair programming; they called it simple, plain programming. You needed to do things in pairs because of the wires or the cards that were cumbersome to use.

Then came the era of industrial programming where, little by little, pushed by the need for automatization and computers being more affordable, programmers were working more and more alone. It was an age of simpler programs, but it took a long time to write, compile, check, fix, improve, write, compile, and so on.

After a while, computers started becoming more powerful and even more affordable. So, companies started automating more complex parts of their business flows. We are talking about financial systems, travel, trade, and so on. You had a complex domain already, but programmers were working alone, as in any other factory. They had a boss, like in any other factory, and a manager, like in any other factory.

The only problem with comparing factory workers with programmers is that programmers need to solve problems that are from non-routine work, while factory workers had a clear routine that might have been subject to change every once in a while. That is the moment when the concept of the knowledge worker appeared in the management literature:

"Every knowledge worker in a modern organization is an "executive" if, by virtue of his position or knowledge, he is responsible for a contribution that materially affects the capacity of the organization to perform and to obtain results."

- Peter Drucker in The Effective Executive (1966)

Pair programming then reappeared in some areas, and younger programmers read about the older ways of programming. They started using it with great success, and it felt very natural to have two people coding for a task. Plain pair programming is a simple system of managing complexity and gaining better results.


Elucidating problems in pairs

The best way of explaining why pair programming works is that two people can understand how to write some code better than just one programmer. It is true that when we code trivial parts of the system, pair programming is unnecessary – even counterproductive. So, it's important to choose when to pair program and when to solo program.

Here are a few situations where pair programming works great, and where the two heads are better than one rule applies:

  • A junior programmer learning from a senior programmer.
  • A new programmer in a team learns from an existing programmer in the team.
  • Fresh tasks are assigned to the team, and two people can tackle the problem better and faster.
  • A programmer learns new practice (that is, test-driven development, unit testing, and so on).

As a rule of thumb, it is a good idea to use pair programming when we have a task with higher complexity, either the technical or the business side. It's good to acknowledge that programmers are more likely to make mistakes in complex or unknown areas of code.

There are situations where we'll have simple, trivial tasks that don't necessarily need pairing, or even more, where pairing would be just a waste of time for at least one of the two. Often, it's a good idea to have this discussion with the whole team. After all, it should be the decision for the whole team on how they use their common time, what the learning or improvement focus is in the next period, and where they can't afford pairing because they need to deliver faster.

Should I pair? Before you start a new task, ask yourself the following questions:

  • How would I benefit from using pair programming?
  • How would the team/product benefit from using pair programming?
  • Would we learn anything useful for the team by pairing?
  • Would pair programming delay a delivery?
  • Would pairing on this task be boring or superfluous?

These questions could help you and your team decide if it's worth investing in pair programming for that specific task. Yes, it is an investment, and you should treat every decision with objectivity and respect for the rest of the team. After all, two heads are better than one in some situations, though in other situations, where even one head wouldn't be used too much, using pair programming would just be a waste of time and energy.

Managing complexity

Following the idea that two heads are better than one, we can use pair programming to manage better complexity.

Let's face it: programmers almost never do the exact same task. It might be that the domain is similar, or identical, but there are so many moving parts in the whole ecosystem, such as programming language, frameworks, external or internal use libraries, programming patterns, architecture patterns, business domain variations, performance, security, scalability, and so on. A programmer needs to think about all these and more when writing code. That is why we can make a strong case when we say complexity is inherent in most programming tasks.

Having two people who look at all the aspects of the code is clearly beneficial. There is a driver who writes the code and a navigator who oversees the code, thinks about possible next steps, thinks about possible caveats, and improves the code while it is being written.

Humans only have one brain, and we can only focus our full attention on one thing. We can pivot our focus from one aspect to another, but that is tiring and during the switch, we might lose some details. That is why the driver focuses on writing the code while looking at low-level details such as code syntax, code logic, framework/library usage, or code formatting. And, at the same time, the navigator focuses on high-level details such as design aspects, architecture concerns, performance, security, and so on.

After all, what pair programming does is split the overall complexity into smaller, less complex parts that are easier to manage. These smaller parts are managed by two people, who use the clear responsibilities that are attributed to the driver and the navigator.

A good guideline is necessary for clarifying the driver and navigator roles before starting the pair programming session. Even if we have paired many times before, or if we are at the beginning of our first pair programming session, it's a good idea to clarify what each of the two pairs will do so that we can manage complexity better. We need to take into account the experience, knowledge, and skill level of both programmers before we start.

In this section, we discussed the history of pair programming and how pair programming can help you. It's a good option to solve complex problems we consider difficult and troublesome to solve on our own. You have now a few good guidelines about when to use pair programming or when it's better to solo program. Next, we'll discuss the various ways we can pair program, depending on our teams.


Sharpening our knowledge

There are several contexts that need to be accounted for when you're using pair programming for learning; that is, collaboration, alignment, and improvement. Let's learn how to pair program in a different way, depending on the team's current level and knowledge uniformity.

Collaborative work

The idea of collective code ownership existed in programmers' lives even before the existence of pair programming. This means that all the code that we write as individuals is our code, and anyone can change it as per their needs. We don't have codebase areas that are owned by their authors. We don't need the author's permission to change anything. However, we do need to obey some rules that can be summed into two areas: improve the code and don't introduce defects.

Pair programming cannot work without you having collective code ownership. There are two immediate effects that occur when you're implementing collective code ownership: it's difficult to know the other author's code, and you remove some bottlenecks as there is no need to wait for someone to do their task.

The most effective way to know a particular author's code is to program with the author. Due to this, pair-programming opens the door to spreading knowledge within the team. There are multiple ways of spreading knowledge in the team, depending on our focus in the short-, medium-, and long-term future. We can focus on people and then decide if we want to improve their skills. Similarly, we can focus on the product/system and then decide if we want to improve the team's knowledge about it. In fact, we should do both, but take the timing into account. Maybe there are moments when it's more appropriate to learn new skills, as we may have good knowledge about the system, or vice versa. If a completely new feature arrives, with its own different and difficult domain logic, it's obvious that we should focus on that, and it's not a good moment to learn new skills.

After all, a team should be more than the sum of its parts; that's when you will see collaborative work. Any team member should be able to help another, and any team member should be open to new skills, practices, tools, and system or domain knowledge, as long as it evolves the overall delivery capacity.

Collaborative work means that we understand and act under the underlying principle that the team needs to work well together, to have continuous improvement. Pair programming is a manifestation of collaborative work, a tool of fair collaboration that fosters productivity and enjoyment for good quality products.

Leveling knowledge

A team needs to have the same minimal level of knowledge on essential topics, be it related to business as well as technical. What better way to level knowledge than two people who have different levels of knowledge to work together?

Of course, this whole process is not necessarily easy, especially if you were used to working alone. It might feel intrusive, cumbersome, frustrating, or even annoying. That is why I wouldn't recommend anyone starting to level knowledge with pair programming without some sort of management or outside coaching.

Using pair programming to level knowledge is a great approach, which comes with a few short-term disadvantages, along with a few long-term ones. First, in the short term, you will see the team being more tired, often with more stress and them delivering below par. Nevertheless, during the next few pair programming sessions, you will feel less and less tired and you will get used to this way of working. In the long term, we have the benefits of real collective code ownership, where anyone can change the code in any part of the system, without the fear of introducing defects.

When we start to level the knowledge, we need to explain the process really well to the team; that is, we need to explain why we are doing this, how it will be done, how long we expect it to last, and what the possible short-term and long-term effects may be. After that, a good practice is to start collecting some tasks that are appropriate for pair programming with the purpose to level knowledge. We don't aim to do full-time pair programming, because it will be extremely difficult for everyone to cope. Rather, in the beginning, it is preferable to do 1-2 hours per day of pair programing. A good practice is to have the first few days be completed under the supervision of a technical coach, with all the pairs in a room and the coach observing and giving advice on how to pair program in an effective way. After that, the technical coach can remain as an adviser, as many questions remain on how to effectively work as a pair.

Advancing knowledge

Once the team has a similar minimal level of knowledge about the business and technical side, the next step is to think about improvements. Often, while leveling knowledge through pair programming, every team member starts having ideas about how things could go better. So, don't miss the opportunity and note down every idea that appears. Often, taking notes about what you would like to learn next is a good approach so that when the time comes to pair program with the focus on advancing knowledge, you have a clear idea of what to do next.

During sessions of advancing knowledge, you can involve a technical coach as well, to make sure that the focus remains on that specific learning activity. A technical coach would make sure there is a prioritized learning backlog for each of the team members, and that they have the time and space to learn.

Let's take an example of a programmer who knows Java and would like to learn JavaScript to help their team's endeavor to implement their next feature, which is user interface-intensive. For that, an experienced JavaScript programmer would pair with a Java programmer. They would take an appropriate task that was in line for JavaScript and work on it together. Of course, the time to finish that task will be significantly higher when the two programmers work together in the beginning, because learning is involved. But after 2-3 weeks of daily pair programming sessions, usually, the time taken to complete such a task is reduced. Now, the Java programmer can take on easy JavaScript tasks on their own, helping the team deliver faster.

Using pair programming to advance knowledge is a very good practice to help the team solve long-waiting lines at specific specialties. In our example, what would have happened if all the Java programmers had to wait their turn until the only JavaScript programmer reached their request from the long list of tasks they needed to perform? We want to avoid that as much as possible. And the solution is not to give all the difficult tasks at the back to the most experienced programmer – we should do the opposite if we want to improve our productivity in the long term. We want to spread the knowledge that is needed in the near future inside the team. In practice, this means that the most experienced people would teach volunteers how to perform simple tasks, thus relieving them of the trivial tasks and letting them focus on the intricate ones. This attitude can bring a huge difference to the overall timeline and success of your software product.

The idea of improving your knowledge through practice is very old. It comes from the medieval times of manual crafts. We can learn from those times and take what can be applied today. Learning while working with someone is very powerful as it brings more positive aspects to the table: observing, working with expert supervision, discussing aspects of the craft, and thus understanding how to do the work better. Now, we will move on and discuss how we can improve our current knowledge base when we pair program.


Gaining wisdom

We can learn and get wiser as we gain knowledge of the profession. Getting wiser can happen by itself, with active learning, constant work, and passion. We can also boost learning and, by doing so, get to the goal of being wiser faster. And the wiser we are, the more we see that we understood less than we initially thought. So, we need to learn some more. Learning never stops. In this section, we will understand this in the context of pair programming.

Improving the system

We can also use pair programming sessions to improve parts of the system. It's a similar approach to advancing our knowledge, but in this case, we are talking about specific parts of the system.

Especially in complex systems, there are people who know it very well; that is, specialists in the domain, logic, and particularities of that part of the system. Usually, if you are a specialist, everyone comes to you to ask questions. But you may also have other things to do – other tasks or parts of the system that you need to take care of. That is when you become a bottleneck for the whole system. The team, coach, manager, or anyone else will need to observe this situation and come up with a plan to pass their knowledge to a few other people. A good practice is to have at least three very knowledgeable people on a specific part of the system. This helps if you want to optimize your development for a fast flow, fast feedback type of development.

When it comes to passing knowledge to a part of the system, we can talk about programmers, testers, analysts, ops, security, or any other role in the team. So, pair programming can be a tool to make pairs such as programmer-analyst, programmer-tester, and so on. We can also extend the whole pair programming approach and lose the programming part. We could have two analysts, for example, pair up in the same way: expert-beginner. But if we are talking about experts and beginners on that particular part of the system, their overall experience wouldn't need to be that important.

Once we've removed these knowledge bottlenecks, we can start thinking about improving the system. Pair programming, or plain pairing, will help the team deliver faster, with some initial time well-invested for the long-term future of our product.

Staff liquidity

This practical approach to advance knowledge, where the most knowledgeable individual would teach others who are less knowledgeable, rather than performing the most difficult tasks, has a name: staff liquidity. The concept of staff liquidity was introduced by Chris Matts during an article back in 2013 (a link for this has been provided in the Further reading section).

Chris Matts explains that there are four levels of knowledge anyone can have for a particular skill or part of the system:

  • 0 – "I know nothing!"
  • 1 – "I can run it."
  • 2 – "I can tweak it or bug fix it."
  • 3 – "I can redesign or refactor it." / "I OWN it!"

Here are the steps we follow to implement this in our organization:

  1. We need to make a list of skills we need to have (for example, Java, JavaScript, unit testing, continuous integration, and so on) and a list of system parts that we need to know (for example, frontend, backend, database, and so on).
  2. We must then list the names of all the team members, one after another. We use the 0-3 marking system to mark the current situation, in a matrix form.
  3. Finally, we need to make sure we have at least three people at level 3 for each line in the matrix. How do we get there? Via learning sessions with pair programming. Budget the time needed for learning and get pairing!

Of course, staff liquidity goes beyond pair programming, but we will only focus on how suited it is for boosting pair programming's extensive usage. You can use staff liquidity in any aspect of the organization where you need to improve a team member's skills, alleviate bottlenecks, increase time to market, or accelerate feedback cycles.

In this section, we looked at some ways to get wiser, and we looked at systemic thinking for advancing learning. Staff liquidity is a very powerful concept that needs to be in every senior professional's toolkit. We can be so much more efficient, and deliver so much more quality, just by organizing ourselves better. And as a bonus, our environment's spirits and morale increases a lot. Next, we'll study how we can conquer complexities in our development systems.


Managing complexities in complex domains

One of the main reasons software development is difficult is because we deal with complexity. Let's see how we can use pair programming in complex, difficult situations, when it helps us, and when we should use other tools instead.

Managing complex domains

The more complex the business domain, the more you need pair programming. And let's face it: even the simplest business domain is complex nowadays.

In areas such as banking, trade, or travel, you can expect from the start that you will have a lot of complexity on your hands. Typically, code written in complex areas tends to be worse in the beginning. It's the "first half-baked draft" that writers so often refer to. This is because writing code is not that different from writing an article, a novel, or a series of novels if you work in a very large organization.

Writers say that it's a good idea to quickly write what's on your mind. No matter how much you struggle to write the perfect first version of your text, there is only one conclusion: it will be horrible. The first draft should be like a lump of clay that you shape after several iterations of reading and improvement. The only problem is that we have a blind spot for errors we've created ourselves. That is why, especially in a complex domain, code review is always a good idea. Or even better, we can speed up the code review with pair programming.

Iterative development happens even in the smallest of programming tasks. We create the simplest form of solution, and then we ask for feedback. The beauty of pair programming is that this feedback comes almost instantly from our pair. Because of this, we feel that we can tackle complex problems easier if we work in a pair.

Difficult tasks

Sometimes, we might feel overwhelmed by looking at a complex task. And we might even procrastinate, just fearing that the task is too difficult, or thinking that we need to prepare more in order to face the new task. This usually happens with tasks that are in a new area for us, something that just attacks our self-perceived competencies. Working in a pair will reduce that fear. It's not just me who's fighting the dragon; I have a pair and if something bad happens, we can think about what to do together. Often, that thought makes me feel like we can get through it.

Pair programming on difficult tasks needs to be done between programmers who have the same level of experience. It doesn't make any sense to have a senior-junior pair, as the junior will be completely lost. The only good solution is to have a senior-senior pair, with the focus on getting things done, rather than a learning focus.

There is this misconception that all pair programming sessions are about learning. In fact, especially in complex domains, we have many more pair programming sessions focused on solving tasks and getting things done.

Context is important. If you have more time at hand, it's a good practice to do pair programming both with highly experienced programmers to advance the task, and with less experienced programmers with the purpose of them learning what the most experienced pair is doing. But if we don't have the time at hand and we need to deliver, we should focus on getting things done. Then, after the delivery or deployment, we need to plan some learning sessions for the less experienced programmers.

The fastest feedback code review

A good coding practice is code review. It has been around since the beginning of programming as a format for formally inspecting code. It can be used to improve the code's format and logic, or as a way to distribute coding or domain knowledge. Typically, the code is written and then there are one or more programmers who will formally review the code. The programmer who wrote the code reads the reviewer's comments and improves the code. Then, the code is passed through the code review once more. This keeps happening until the reviewers accept the code as it is. Because the subsequent code reviews can take a long time, the code can only be said to be done after many days. It can even take a few weeks for the initial code to pass the cycle of reviews and changes.

Let's think about how the code review can be done while the code is written. We have a driver, the person who writes the code, and the navigator, the person who observes mistakes, incorrect names, logical errors, domain mistakes, performance issues, and so on.

If we go by the classical code review format, we have a few weeks to get from the initial form to the final form, but with pair programming, you only have a few hours. Also, by using pair programming, we remove the overhead of writing improvements, reading improvements, and having meetings to understand the given feedback. Also, the overhead of learning how to use a tool for code review disappears.

Since it is a good practice to have more points of view when we're doing code reviews, we could do the same with pair programming. We can change the pairs often, so that more programmers can look over the same code while working on the feature.

Minimizing the defect rate

One direct outcome you would expect is to have less defects in the code that was written by using pair programming. The reason for this is simple: two heads are better than one.

The cost of fixing a defect becomes higher and higher as time passes. The classical approach of fixing bugs, analysis - coding - testing - analysis - coding - … - done, can take a long time for a new feature. And the defects that were not caught in this very long cycle will be even more difficult to catch later, after the code is in production. The more time passes by, the more difficult it will be for anyone involved in that task to remember what is going on. That is why we need to find ways to minimize the defect rate right from the beginning. We can maximize the feedback loops in order to minimize the defect rate.

Besides having a cross-functional team that uses practices such as continuous integration, unit testing, or test-driven development, a very good practice that's used to minimize defects is pair programming. With pair programming, you can catch simple logical mistakes in a second, just because you have a navigator who is always watching and trying to understand the code the driver writes. You cannot have a shorter feedback loop than a few seconds when you're fixing a defect!

Complexity is a hard thing to grasp, especially when you are in the middle of the action. It's like wanting to count how many trees are in a forest, while you are in the forest. The first thing you must do is go back a few steps and get a bigger picture of everything. Apparently, obvious things can help us: fast feedback, transparency, openness, and close collaboration.

Next, we'll discuss how we can make our future selves' lives more comfortable!


Comfort for the future you

I am always stupid in my own eyes when I look at the code that I wrote 6 months ago. I do get it, but I would have liked to have written it better, in a more elegant fashion. I always have mixed feelings: I feel good because it means I learned a lot in the meantime, but I also feel like I haven't done a good enough job. This is a problem for any content creator, writer, programmer, and so on. Let's learn how to create comfort for our future selves by putting quality first.

Code is more often read than written

We often look at some of our older code and reading it is difficult. We know that we work in a complex domain, where we need to know so many things just to get started. We need to know the technology, the syntax, the business domain jargon, and so on. Considering that we know all that, it still so happens that older code (even from a few months back) is very difficult to understand.

The question is: why did we write such a bad code? It has happened to me more than once when I have had to look at some older code, got annoyed, and said this code is a mess. Then, when I looked at the author, it was none other than me. This illustrates that I'm maybe a better programmer now than I used to be. Or, it says that I needed more improvement feedback on that code, either via a code review or a strict pair while writing it.

If, during our pair programming sessions, we focus on the readability, clarity, and usability of the code at hand, we will certainly have better results in the long term. It's often not enough for just one person to write the code and ship it. There are always improvements that we can make to that initial code.

Think about all the people who read your code, and how much time and effort would be spared if we took the time to write some code that is easy to understand. Of course, this comes with a cost, but we need to balance the time it takes to write the code and the time we imagine will be spent reading and understanding the code.

Pair programming comes with some help for this situation. One of the navigator's main jobs is to read the code over and over again, from top to bottom, and think about how easy it would be to understand it. Then, they need to stop the driver and come up with improvement ideas on naming, domain jargon, coherence, brevity, and so on.

Exploratory testing with pair programming

Imagine that you have a programming task and a tester sits next to you, immediately testing the code you have written. Well, that might be an exaggeration, but at least the tester is doing a live code review with a clear focus on testing.

The tester's mindset is to think about how the system under test would be destroyed, while the programmer's mindset is to think about how the system needs to be created. Without a doubt, a programmer is highly optimistic and believes all will be good. A tester is highly pessimistic and sees potential cracks in the system, including errors, issues, and so on. This optimist + pessimist couple is great because together, they can spot the correct implementations, errors, defects, or bad names from the code.

Exploratory testing is a way of testing where test cases are not created in advance and repeated, but rather the testers check the system on the fly. The tester looks at the product or explores it, with the fresh eye of a new user that will not respect the direct, clear path of using the system. A tester would try to fill in wrong data, or almost wrong data, go back and forth through the user flows, they might refresh or write really fast in some areas, or click on a button frequently, all to see what might happen and to explore if the system was taught to be resilient enough in such circumstances. Exploratory testing requires a different mindset, and it involved a lot more than what I've just stated. But there is a clear difference between checking a system based on a set of plans and checking a system by using exploratory testing.

When talking to testers who are experienced with doing exploratory testing, I have often heard that code review is a form of exploratory testing, but on the code. Furthermore, on-the-fly code review is an improved form of exploratory testing. Testers might call this format of pair programming (programmer driving + tester navigating) exploratory testing as well. It's revealing that this is the form of exploratory testing that has the fastest feedback loop of seconds or minutes.

Using exploratory testing techniques on the fly, while the programmer is writing the code, is the fastest way of minimizing the number of defects that occur when a tester is involved.

Next, we'll explore how to interact with peers who are not specifically from or understand the workings of a technical world.


Programming with your CEO

Business is why we build software. If it weren't for ideas that bring value to other people, then software wouldn't exist. Programming has a lot of jargon, a language not accessible to non-specialists, that is not easily understood by all. But if we were to work with non-specialists, they should understand what we are doing as well, as long as they know the business. So, in this section, we are going to discuss some aspects of improving our interactions with our peers.

Social programming

We may want to improve the social interactions inside the team, and pair programming is a good practice for that. While working on our computers, we must remember that we work for and with other human beings. Quite often, and unfortunately not always, the code we write will be used in a direct or indirect form by many people. So, it's important to also remember the social aspect of programming.

At the same time, our team, our product team, and our organization are made up of people who can learn and teach many interesting things. Because of this, we can take advantage of this and use pair programming as a way to learn faster from our peers.

Social programming means that we want to learn, share, and work with other people, explaining what we know while being humble and learning from others with openness and curiosity. Pair programming enables all these, as we can take the opportunity to learn and share. This mindset is extremely beneficial for all the team members, as it fosters continuous overall advancement in all areas.

Pair programming is a tool that's very appropriate for social programming, as you're trying to improve the social interactions of a team. Often, people think about pair programming as a tool to code together, to minimize defects, and that's it. But almost half of the activities I do as a technical coach with teams have to do with soft skills, social skills, or human interactions.

It's important to know how to talk to your colleagues, give and receive feedback, and communicate with other roles or managers from the rest of the organization. I always ask programmers: how would you explain this code if you were to pair program with your CEO? This situation might sound funny or absurd, but if you can clearly explain to a CEO, without the whole technical jargon, what that code is doing, it means that you know what you are doing really well. And it also means that you have excellent communication skills.

As a side note, during a community event that I was facilitating, while the programmers were pairing, a CEO appeared. He heard about this event and he was curious what was going on. Nobody had any idea about his role, and he joined, paired, and discussed just like any other attendee. Only after the event did I find out that he wasn't really a programmer. Imagine if you behaved the same if you knew that your CEO was joining you during a pair programming session. This is a good example of social programming, even without programmers being involved.

The rubber duckling effect

One particularly interesting way of using our cognitive structure is by utilizing the rubber duckling effect, or teddy bear pair programming. A debugging study that was performed with students in 2012 showed that when we have a problem, the best solution is to verbalize it. When explaining our problem in detail, our brain works in such a way that we start finding the solution for the problem at hand ourselves. Apparently, we don't need to talk with someone to give us advice; rather, we just need to talk, even alone, and in most situations, we'll find the solution ourselves:

". . . [an] effective technique is to explain your code to someone else. This will often cause you to explain the bug to yourself. Sometimes it takes no more than a few sentences, followed by an embarrassed "Never mind; I see what's wrong. Sorry to bother you." This works remarkably well; you can even use non-programmers as listeners. One university computer center kept a teddy bear near the help desk. Students with mysterious bugs were required to explain them to the teddy bear before they could speak to a human counsellor."

– Kernighan, B. W. and R. Pike (1999). The Practice of Programming. Reading, Massachusetts, Addison-Wesley

Pair programming takes advantage of this quirk. A good practice is, even before we start coding, to explain to our partner what we want to do. If there are gray areas where we don't have an answer, we will find an answer just while talking. And for the majority of the areas where we really don't have an answer, our partner will help us. Typically, during a pair programming session, we either solve all the problems in the beginning, or while they appear, or we have a blockage and we need to talk to our colleagues. The first situation occurs far more often, but there are situations where we'll need to have a break or have a discussion with other colleagues.

Of course, we can use the rubber duckling effect even without having a person in front of us. I personally use a teddy bear and I explain what bothers me. I know that it may sound weird, but you need to try it for yourself without a lot of judgment. You will see how much it helps.

Yes, it sounds silly to talk to a rubber duck, a teddy bear, or your favorite toy animal, but it works. And hey, reach out for your inner child and think about playing a bit. Being playful is a lot more useful for our imagination than being serious. Often, good solutions come when you start playing and open the imagination door.

Next, we will learn how to use pair programming within our respective jobs.


How does pair programming work?

We want to be responsible for our own successes and failures. That is why we need to take some decisions into our own hands. When we really know some things can be better, or how a thing will be better, we need to fight for it. Sometimes, we win, sometimes, we lose, but it's important to have an intellectual debate about how to use our time, what we should learn, and the options for the tools and technologies appropriate for the job.

Knowledge work and knowledge workers

Programmers deal with knowledge every day. They take some raw information, and they try to shape it into systems. This whole effort is not a simple one; it requires a lot of analysis power, abstract thinking, and discipline. It is always an endeavor of partial results, slow progress, frustration, and enjoyment.

Continuing this train of thought and using the concept of knowledge workers that we introduced previously, we can conclude that programmers are knowledge workers. And not only programmers, but everyone in any software development team is a knowledge worker. This view is essential when it comes to thinking about the activities that we need to perform in a software development team.

Learning is not optional when we're dealing with knowledge work. I often get this question: how can I convince my manager to let us learn X? If a software development team doesn't learn, they are doomed to create low-quality products, with high maintenance costs. Looking just at the momentary time costs of learning is a very narrow and unjust way of looking at this. We always need to look at both the short- and long-term benefits of whatever activity we set out to complete.

Use pair programming as a tool so that you become a knowledgeable knowledge worker, with the appetite to learn more, always improve, and strive for the best. Have pair programming sessions where you focus on optimizing your learning time for the vast amount of knowledge that might be right there, in your team.

Time well spent

I am sometimes lazy, and a pair drags me out of this comfort zone that I'm in. When pairing, you often feel a bit obliged to be there in terms of your full body and soul, so you don't have any phones, messages, chats, emails, or other side activities. In my personal experience, it is a good type of obligation – the one that gets me out of a state where I'm not very productive.

When in this state, I often feel really productive while pairing, compared to what I was doing just by myself. And that feeling is real and can be doubled by metrics. That is, if we count just the time spent versus the tasks that get completed, while forgetting about the better quality while pairing.

Often, I hear the following idea: how can two people work on the same task? It's absurd to lose the time of two people because you will produce just half the work! But things are more complicated than this, and not always 1+1 = 2, especially when we're dealing with people.

Think of pair programming as a catalyzer that makes the whole reaction a lot more effective. If we make the whole experience of pair programming a nice and attractive one, we will have larger benefits than if people were to work alone, by themselves.



Pair programming can improve the whole development process of an organization significantly if it's implemented right. You can have a more enjoyable work environment while you're working closer to your peers. Pair programming is a practice that can reduce code defects, by letting more eyes see the code from an earlier start, and thus helps solve defects sooner and in a cheaper way. Also, because more people look at the code, the end product will be code that is easier to read, easier to understand, and, in conclusion, less prone to defects for future programmers who will change it.

If you haven't experienced the real power of pair programming, now is the time to continue reading and learn how you and your team can benefit from it. Furthermore, you can try remote pair programming, which is the same as pair programming, but it entails using a few different tools and there being a slightly different experience than doing pair programming in person.

It's never too late to start pair programming. I often paired with people who had at least double my experience, and they were pairing for the first time. If conducted well, the first pair programming session can open the eyes and hearts of any software professional.

In the beginning, it might be tiring, feel tedious, or be plain weird because now you need to explain your code to someone, often a stranger. But after a while, as with any learning curve, it will become easier, and you will feel the benefits.

So, I invite you to read further on how to try and succeed with remote pair programming in your organization. In the next chapter, we will look at how pair programming can help a team learn faster, either from each other or from someone outside the team.


Further reading

About the Author
  • Adrian Bolboacă

    Adrian Bolboacă has International experience in product & software development for more than 15 years in small and large companies, with customers from various European countries. He is an experienced trainer - he likes to teach passionate people from dynamic companies to exceed their potential by challenging their current activity model for better collaboration, performance, and satisfaction. Adrian has trained and coached individuals and teams on both technical and organizational sides on topics like architecture & software design, agile and lean transformations, visual management, continuous improvement, Scrum, Kanban, unit testing, TDD, pair-programming, clean code, rescuing legacy code, and much more.

    Browse publications by this author
Practical Remote Pair Programming
Unlock this book and the full library FREE for 7 days
Start now