I love Pair Programming. Typically blog posts about Pair Programming are about different modes to share knowledge. This blogpost 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 process. Every phase, there is an unnecessary motion to the next person .
The waste from these phases increases the lead time for of a team. But getting our lead time is on 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 what
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 it is tough to achieve this zone.
In the office, there are so many distractions that keep you from achieving this zone. Noise from 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 much less a problem. You hardly have to disrupt a teammate in their workflow to ask a question because you have your buddy to ask questions. And even better! This buddy is up to speed about the current problem you are facing. You are together in the thick of it. 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. The never need to set time apart to meet up as it is the default.
But I also frequently hear developers say and I experience myself as well that it is easier to concentrate during pair programming. If you are pairing, you use less intense bursts of concentration is my theory, because you ping pong between engineers. Your brain is not constantly outputting as it would if you would develop on your own. You watch the other type or you discuss the problem. During these times you take sort of a nano break. Your mind rests. Together, you get into a productive zone together. 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 Code Review on the code repository is not the only way you can perform code reviews. Traditional Code Reviews is just pair programming in asynchronous isolation that 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. The 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 no ramp-up or context switch overhead.
You achieve with pair programming the same benefits as a standard code review. Knowledge is shared as both know how you solved the problems. The code is maintainable as you collaborate during pairing. 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 of just glancing over the code.
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 and you discuss face to face 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 now, 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 this and find 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. You didn't have it wait in a phase for days, but instead have a flow towards done.
Using pair programming, I have deployed new services in days instead of weeks. You should try it!
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.