Enable javascript in your browser for better experience. Need to know to enable it? Go here.

The root, branch, leaf and fruit of pair programming (part 1)

As a Tech Lead, I helped our account build a distributed team of more than 10 people this year. Pair programming yielded great results for our project, but first we had to make sure everyone had a similar understanding of the concept. This article will dissect pair programming layer by layer from "root to branch, leaf and fruit" to give you a better idea of what it entails. 



1. What is pair programming


Pair programming is a core practice of extreme programming. It’s implemented with simple design, TDD (test-driven development) and refactoring. In a narrow sense, it refers to two people working together to write code, but it can also mean two people with different roles who work on solutions together, etc.

Image depicting a tree representing the root, branch, leaf and fruit of pair programming

2. The root of pair programming


Software development is a process of knowledge transfer and consumption. Team members should have a comprehensive understanding of business, architecture, design and implementation to develop the software that can continuously and efficiently satisfy business needs. The root of pair programming isn't a programming method, but a method of knowledge transfer and skill building among team members.


I hadn’t experienced pair programming before joining Thoughtworks, but I’d always been curious... On the first project after I joined, a back-end colleague familiar with the existing project had to be transferred to another project team. The team expected me to be able to take charge of the backend independently, which I found stressful. Just when I was about to take over, this colleague invited me to pair up together. I thought it would be inefficient for two people to work on just one user story card, but after a two-hour pairing session, I found that my overall understanding of the project had markedly improved. I quickly “stole” the knowledge he perfected so that  I was able to understand the structure of the project myself. This experience showed me that pair programming is in fact much more conducive to the transfer of knowledge.


In our team, pair programming is implemented together with simple design, TDD and refactoring. When a pair gets a story card, everyone performs tasking on the card first. Before tasking, the pair will have a simple design and have already communicated with each other in detail. If one party cannot convince the other to use their design scheme, it probably means it isn’t simple enough. During pair rotation, if one person is rotated to a different role and cannot understand or form a consensus on the current design, then the design is too complicated.

In practice, it’s difficult for people to stick to TDD. They think they can identify the business and technology of a story card according to their own understanding, and complete the task themselves. But they can easily fall prey to overconfidence, or come to the conclusion that there’s no difference between writing tests first and not writing tests. If there’s no supervision, they may lower requirements and eventually give up TDD altogether, falling into an anti-pattern of writing functional code first and then testing. On the other hand, if two people can keep each other in check, TDD will be easier to stick to. 


We also found that pairing can help us find code smells faster and improve code quality through refactoring, making debugging easier. When someone writes code, detecting code smells is hard for them. Another pair of eyes helps you think about the problem from a different aspect, which is conducive to code smell identification and reconstruction.

3. The branch of pair programming


Now, how can we make the tree of pair programming grow leaves and bear fruit? It’s inseparable from the support of the trunk and branches. There are two ways of branching in pair programming.


Driver and navigator mode

The driver designs the program, writing tests first and then functional code. The navigator leads the operation of this pilot, leading test writing and functional code. At the same time, the navigator checks the driver's operations, considers whether the unit test is written correctly, the degree of coverage, whether the code needs to be modified and improved, and helps the driver to solve specific technical problems and query information. This is basically suitable for all scenarios.


Ping Pong Mode

We can have one person write the tests and another person write the functional code, just like playing ping-pong. This is more suitable when the team uses TDD. It can also help the less focused person integrate quickly.


With these two modes of pair programming, code review activities are carried out among only two people, maximizing code review activities to the limit, making our communication more efficient. Keep in mind that pair programming should be freely chosen and used flexibly, it should not be mandated and run dogmatically. It’s best for the two developers to decide their own appropriate way.


In the next article, we’ll detail the “leaf and fruit” of pair programming.

Disclaimer: The statements and opinions expressed in this article are those of the author(s) and do not necessarily reflect the positions of Thoughtworks.

Keep up to date with our latest insights