My initial reaction to the concept of pair programming was somewhere between bafflement and derision. How can two developers working at a single computer be more efficient than one? Is this just another ritualistic relic from the cult of Extreme Programming? Does it work?
The research around pair programming is a mixed bag. As with many quantitative studies of complex behaviour, I find myself with more questions than answers. Are the results the same for professionals as students? Does the type of task matter? Do the results change the more you practise pair programming? How do you measure the long term impact?
Leaving aside the question of whether pair programming is objectively ‘better’, the best we can do is try it for ourselves. For me, the more I’ve practised pair programming, the more it seems to make sense.
Something strange happens with the superposition of two minds on a problem: good ideas get amplified, mistakes cancel out, lazy shortcuts become less tempting, and virtuous refactoring opportunities become hard to resist.
Unlike code reviews, feedback from pair programming is unfiltered and immediate. Your observer becomes your real-time map reader, assistant, spellchecker, and life coach.
There are also benefits to the team. A team that practises pair programming has a lower bus factor than one that works in parallel, even if the parallel team regularly performs code reviews. This means that if you program in a pair, you can cross the road with that bit more chutzpah, safe in the knowledge your team can continue in your absence.
I am not an expert in pair programming. A lot of this advice stems from faults that I recognise in myself! Regardless, here is my advice to get the most out of pair programming.
For the driver
Don’t feel pressured to code differently, just because you’re pairing. If you normally start with an ugly hack and gradually refine it, that’s fine. If you prefer to think through lots of different options before laying a ‘golden egg’, that’s fine too. The observer is there to augment your normal coding experience with gentle course corrections, so don’t feel the need to radically change your approach because someone’s watching.
Think out loud
Provide a commentary on what you’re doing, what you’re thinking, and where you’re going. To get the most out of your observer, you need to keep them engaged. The best way to do that is to think out loud. Justify what you’re doing and why you’re doing it. If your observer can follow your train of thought, they’re more likely to provide helpful suggestions. This is especially true if you’re an IDE ninja who surfs between files at breakneck speed!
Take the time to check in with your observer. Simple questions such as “does that make sense?” and “can you think of any assumptions we’re making here?” will help to keep them engaged and show them that you value their input. Be aware that your observer might be reluctant to interrupt your flow, so giving them regular opportunities to ask questions and provide feedback will be appreciated.
Diagrams are a fantastic way to map out the code you’re about to write. It doesn’t have to be formal UML, but a few squares in a notebook (online tools such as Excalidraw work well if you're working remotely) can show your observer what you’re about to do. Your observer can refer back to this diagram if they get lost to help them make sense of where you are in the code.
With great power comes great responsibility
Remember that you are in a privileged position by holding the keyboard (and mouse if you're a n00b 💥). You’re the voice of your pair. Don’t abuse your power by ploughing on in the face of disagreements. If you disagree over something, stop and resolve it first. Go out of your way to show that you’re open to other opinions.
For the observer
Staying engaged as an observer is one of the most challenging aspects of pairing; It's even more difficult when pairing remotely. Manage your concentration levels by taking regular breaks. Be aware when you are becoming more distracted and do something else.
If you find that you regularly struggle to stay engaged, it might be a sign that you are not rotating the driving enough. It might also be a sign that it’s not the right pair for the task.
When you notice your driver make a mistake, don’t call it out immediately. There’s a chance that they’ve already spotted it, and it can be frustrating when someone calls out every typo that you make as you’re making it. As you pair more regularly with someone, you’ll become more attuned to the best time to interject without interrupting their flow.
When you spot mistakes, consider how to bring it up. Sometimes asking questions can be a gentler approach (e.g. “did you mean to reassign that variable?”).
There are often multiple solutions to a problem. If, as an observer, your goal is to guide the driver to the solution you would have written yourself, you’ve missed the point. The driver might take a different route than you would have, and that’s fine. You can provide guidance, corrections, and suggestions, but let the driver choose the route.
Pairing should be a collaboration, not a peep show. As an observer, you need to stay curious about what you’re doing and why you’re doing it. Ask questions. If you don’t understand, ask for an explanation. Challenge the driver to justify what they’re doing.
Not just the code
Remember that you’re not just observing the code. You can pick up a lot by observing someone else’s workflow. How do they approach problem solving? What was that keyboard shortcut they used? What was that magic script they ran? Pick and choose the best bits of the driver’s workflow to supercharge your workflow.
Also posted on Medium