I love Pair Programming. Typically blog posts about Pair Programming are about different modes to share knowledge. This blog post is pure about cranking out features. It is a way to deliver higher quality software faster. In this blog post, I will explain why.
Many development teams define a refinement phase, development phase, a testing phase, and an acceptance phase on their work board. Sticky's or virtual stickies take a journey traveling through different phases until they arrive at the done column. The phases help teams ensure the necessary work is done to provide a qualitative product increment.
But every phase a work item has to travel through creates waste. If you look at the 8 wastes defined in Lean, you could identify that each phase introduces these types of waste:
- Transport: a work item transitions between one developer to another developer, tester, or product owner to perform the next phase.
- Inventory: every phase can build up an inventory of tickets waiting to be processed.
- Motion: An incoming work item needs to be understood before it can be processed. Every phase, there is an unnecessary motion to the next person.
The waste from these phases increases the lead time for a team. But getting our lead time is one of the most important metrics to focus on. Lead time is a statically relevant predictor of software delivery capability and in turn, organizational performance. This is shown in the research discussed in Accelerate: Building and Scaling High-Performing Technology Organizations. So we want to reduce phases to increase lead time.
Pair programming allows you to complete every phase quicker by reducing waste. Some teams just end up with only a Doing phase. You can scrap phases without leaving essential parts of the development cycle out. Let's see how pair programming can be used in every phase.
Software development consists of completing complicated tasks that require Deep Work. Deep Work is a zone where for extended periods you can do meaningful and hard work. But tough zone to achieve this.
In the office, there are so many distractions that keep you from achieving this zone. General noise in the open office. Someone asks you a question. A teammate asks you to do a Code Review. There is a meeting.
But if I am pair programming, I am constantly talking with my pair program partner. This makes the background noise much less a problem. Your team introduces much less disruptions to each other because everyone has a buddy to ask. And even better! This buddy is up to speed about the current problem you are facing. You are together in the thick of it. This makes development more enjoyable in general. It is a social thing now instead of you breaking your head over something all alone.In the next section, you will read why code reviews are obsolete. I see teams heavily doing pair programming have a lower number of meetings as they are much more in sync. They never need to set time apart to meet up as it is the default.
So I frequently hear developers say that it is easier to concentrate during pair programming. I experience this myself as well.
My theory is that if you are pairing you use less intense bursts of concentration. Because you ping pong between engineers. Your brain is not constantly outputting as it would if developing on your own. You watch the other type a new section of code or you discuss the problem. During these times your brain takes sort of a nano break. Together, you get into a productive zone. You keep each other focused on solving the problem.
Together you are smarter. That is why I think you get easier into a zone of shared Deep Work and can solve complicated problems together more quickly during the development phase.
Research on Code Review shows that it is a valuable tool in reducing code defects, increase code maintainability, and knowledge sharing. But the typical pull request into the code repository is not the only way you can perform code reviews. Traditional Code Reviews is just pair programming in asynchronous isolation. On top of that: it is slow.
For example, someone creates a pull request on Monday. It gets reviewed on Tuesday; the comments get fixed on Wednesday. If you are lucky, the work can be finished on Thursday and deployed. Does this sound familiar?
But with Pair Programming, you give the review comments instantly and fix the problems on the spot. This instant feedback is a massive speedup. The reviewer is not only commenting and trying to explain the problem, but he can take over control and fix it himself. There is overhead from ramp-up or context switching.
You achieve with pair programming the same benefits as a standard code review. Knowledge is shared as both know how you solved the problem. The code is maintainable as you collaborate during pairing to write good code. Defects are just as well spotted during development. I suspect the reviewer finds even more defects as he intimately knows the code. If you are really honest, keeping attention is hard after a couple of reviews or a very long review. I sometimes catch myself just glancing over the code after a long day.
Asynchronous Code Review can create social tension on both sides for the reviewer and contributor. It is easy to just go at it if you are typing comments on a computer screen. There are enough blog posts on how to do an excellent code review without becoming personal. In a team with trust and maturity, this should not be a problem. You can never blame a single person if it does happen. But it still happens.
But with pair programming, the code is written together. It gets instantly reviewed. So there is no feeling of ownership of the code yet. It is both your code. You can explore synchronously each other's points of view. You can easily experiment with both solutions on the fly and see what works better. Pair programming dramatically reduces the social tension of different code approaches.
A code review can still be useful for sharing knowledge. But by after pair programming, you should not find any maintainability or defects frequently enough to warrant another code review. If this is the case, then without pair programming, you probably also experience this large number of rework after code is initially written. There are deeper problems within the team that people cannot complete work on their own.
Pair programming greatly speeds ups the testing phase. You can easily do TDD with one writing the tests and the other implementing the code for it. While one is coding, the other is looking for additional tests that the engineers should implement.
While pairing, false assumptions are spotted more often. As you are explaining the code or writing a test, your partner can have a different understanding. You can easily discuss the assumptions and discover the truth. The difference in these understandings is where false assumptions hide. These are not always found during asynchronous code review.
By discussing, you explore what tests are important and valuable to test. You add more valuable automated tests instead of the easy ones. I find myself pushed to greatness by my partner. If I should really write a test, but it is more difficult, I feel myself sometimes being lazy and don't implement it. But during pair programming, I am actually too proud to admit defeat, I want to show off and do write the test. Also, it is easier to do difficult things together, so you try it more often. Social factors have an impact. You might as well use them in your favor!
When you completed the work, you both created the code, you have tested it, and it is ready to be shipped. All without putting work items through different phases where it introduces wastes. You didn't need to transfer the item to another person. It didn't have to wait in a phase for days. Instead, you just get it done and ship it!
Using pair programming, I have deployed new services in days instead of weeks.
In a big team, you can ask at stand-up who will collaborate with each other to get items done. A strict Work-in-Progress limit also helps in forcing people to collaborate and pair programming.