The reason pair programming has never been as popular as other agile practices may be that we want to jump straight to coding and design as we go along. That doesn’t work in pairs. Designing in pairs but coding and reviewing on your own is a compromise worth considering.
Comment (0) Save Tweet 3,750 Views
Pair programming has a long and respectable history. Frederic ‘No Silver Bullet’ Brooks practiced it as early as 1953. It makes Scrum, CI/CD, and BDD look like recent fads by comparison. I’ve worked in teams where the latter were practiced with a good deal of commitment and success, but pair programming has never been popular. I am not surprised. I must have racked up no more than a week of solid pairing during 22 years as a developer and I wasn’t convinced of the alleged benefits.
There’s a slightly unsavory intimacy about using the same keyboard, mouse, and monitor that doesn’t work for me at all. I don’t like other people manhandling my keyboard or mouse, pointing their finger at and even against my screen – the horror! I am picky about my peripherals and often spend my own money on the best quality there is. My development environment is set up just the way I like it, with custom key shortcuts that don’t make sense to anyone but me. It’s not set up for other people’s convenience.
Now, these physical barriers needn’t be a deal-breaker. You can swap keymaps in your IDE. You can attach two keyboards and mice to your workstation – and order a bigger desk. Or you can each stay where you are using IntelliJ’s code-with-me plugin and the physical distance doesn’t matter anymore. Yet no physical aid can make the practice any more appealing to me. It’s the mental challenge of working on the same piece of code together. The way we tend to code doesn’t scale well to more than a single brain.
Coding Is Not Like Peeling Potatoes
The school of pair programming tells you to switch roles between writing the code (the driver) and observing/reflecting on what’s being written (the navigator). They insist on that division not just because using the same mouse and keyboard at the same time is cumbersome. The reason we need to rotate these distinct roles is because of the mental processes of writing code. You can’t coordinate two brains to produce a single line of code in tandem. You can’t divide up the task, therefore it can’t scale. Peeling a sack of potatoes is perfectly scalable: just take half a sack each. Coding is a thought process that must come out through an ancient QWERTY interface until Elon gives us all a brain implant. The typing itself is an overrated skill.
Any code I type starts as an extremely ‘drafty’ version. I arrange and re-arrange my thoughts through the code on my screen. Modern IDEs and strongly typed languages make it a breeze. I don’t have a full mental image of the program in my head that my fingers can just turn into a bug-free executable. I type something and throw it out a minute later when a better alternative pops into my head. I don’t want anyone looking over my shoulder because it’s exhausting to explain myself verbally each step of this rocky road. This can’t be much fun for the other party. They have to sit in forced silence until there’s a piece of working code that they are invited to have an opinion about.
It doesn’t have to be like this. After all, it is called pair programming, not pair coding. The two are not the same thing and many others have made the same comment in the context of pair programming. Coding is a vital part of the much broader discipline of programming, which includes specification and design. Yet we tend to equate the two as if coding is all that matters. Why has the development community at large become so dismissive, even scornful, of up-front design? We take a business requirement and jump straight to code, iterating towards an acceptable version and hoping an elegant design emerges as we code. Even when it works, coding like this is doomed to stay a solo exercise for all the reasons I just explained. The older proponents of pair programming very likely came to the table better prepared, with more detailed specifications and designs. Their Emacs wasn’t loaded with all the refactoring goodies we take for granted. The mental process to arrive at working code must have been much more structured and therefore suitable to do in pairs. That makes all the difference.
Allow me a little interlude by way of comparison. A stage play consists of dialogue for the actors to interpret, much as lines of code are interpreted by a virtual machine. Writing the dialogue usually takes less than half of the entire writing job, although it is 100% of the finished product. A dramatist develops the plot and character by writing imaginary biographies of people in the play. There is an iceberg of preparation that can take months before you write a single line of dialogue and even then, you go through several revisions of the dialogue. You can always make a phrase more catchy, more emotional, or more informative. The same goes for iterations of writing code. The more up-front design doesn’t mean the first time right. But the changes will be smaller and less sweeping. There are still many ways to Rome, but the journey will have fewer unexpected detours.
Do We Need Two Pairs of Highly Paid Eyes?
Our habit to design by coding may just be the reason why pair programming never caught on. It makes it an unappealing if not impossible option. Yet this straight-to-code approach is a habit you can change. We can gather our thoughts in pseudo-code and free-format diagrams. This works very well in pairs. The results will be a better mutual understanding of the task at hand when you start coding. However, if the two of you have made a sufficiently detailed design of the code-to-be it begs the question of whether it is still worthwhile to have two highly paid pairs of eyes during the actual coding stage, just to avoid implementation errors. I don’t think it’s worth it. In the ‘olden days’ of waterfall rolling out new versions of code was vastly more expensive compared to a good set-up CD pipeline in a cloud infrastructure. First-time right actually made sense back then.
I can do without pair coding. I am not convinced the quality gains outweigh the extra cost, and I am quite sure I don’t need it to feel happier in my job. But I would welcome a lot more collaboration in the specification and design stage. There are always requirements to software. The problem is we often don’t make them sufficiently explicit. Figuring them out from source code is exhausting and painful. Fleshing out the requirements, solving ambiguities, eliminating assumptions: all these had better be addressed before coding. The good news is that they are much, much better suited to a pair treatment than coding. A group of three or four will also work fine. This is the stage to ask questions, find answers and get everyone on the same page. This is where you discuss and define your APIs and data/transfer models because they are more design than implementation. This is where you write your Given/When/Then scenarios in plain English for behavior-driven design. The group setting is where you address anything controversial and reach a consensus on the direction to take.
Design Together, Code, and Review on Your Own
Implementation in working code will be quicker and less contentious after that. You have a detailed grasp of the requirement and any serious differences of opinion can be resolved before you start coding. After designing together, the pair or trio parts ways and implements the code on their own. Later they review each other’s work thoroughly, a practice that many teams alreadyfind valuable. An added benefit here is that the reviewer will have been involved in the design of the code, which guarantees better understanding, fewer surprises, and higher quality of this vital review stage.
I must press one important parting thought. The approach I outlined is not a return to comprehensive up-front design. Design should be detailed, but each design session is concerned with a manageable chunk of work representing no more than a day for each developer. In practice, that means getting together every day for an hour to 90 minutes and basically create software without writing code. I have tried it, and it works. Please don’t treat it as a meeting. It is actual work and can be really fun too.