In past posts, I’ve written about various pairing styles such as ping-pong and strong-style pairing. One style I haven’t touched on yet is Driver-Navigator, which I cover in this post.
If you’re new to pair programming, you’re often advised to start with Driver-Navigator. This is only because it happens to be the most well-known pairing style. Corey Haines points out that this style of pair programming is actually an intermediate-level style. In other words, it’s suited more for software engineers who already have significant experience with pair programming.
In order for this style to work, the pair needs to have good communication habits, constantly keeping the other abreast of what thoughts are going through their head. Unfortunately, this level of communication isn’t necessarily built-in to a new pair. Because of this intense communication requirement, I generally consider the Driver-Navigator style of pair-programming to be a more intermediate level style.
— Corey Haines (Understanding the Four Rules of Simple Design)
Prerequisites to Driver-Navigator
A pair of software engineers who are new to pairing with each other or the codebase should consider starting with an alternate pairing style, even if they’re both experienced in pair programming. For example, using strong-style is a good technique for exploring a new codebase, while ping-pong is a good approach for getting comfortable with a new pairing partner.
Let’s say that the pair has found their bearings with the codebase and have established an effective rapport with each other. There are still two additional prerequisites for a successful Driver-Navigator session.
Shared Understanding of Pairing Roles
Fundamentally, a shared understanding of the roles in Driver-Navigator is needed: what each role is responsible for, and what they can expect from their pairing partner. I have found that these responsibilities and expectations are often misunderstood, so it’s good to go over them with your pairing partner.
Driver:
Responsible for the current step, but may think ahead to the next step. For this reason, “Driver” is considered to be the “tactical” role
Thinks aloud so that the Navigator can follow along
Decides when to break for discussion or when to swap roles
Navigator:
Thinks many steps ahead. “Navigator” is considered to be the “strategic” role
Listens attentively as the Driver “thinks aloud”
Takes notes on:
Observations of what the Driver does and how they do it
Options for where to take the code, what to prioritize next, etc.
Tries to answer any questions that the Driver asks
Offers solutions when there is a failing test with an obvious and straightforward fix (e.g. a typo or missing syntax)
Lets the Driver decide when it’s time to break for discussion, or when to swap roles
The pair may also decide to enforce frequent role-swapping through the use of a timer
Both:
Agree on a working agreement1 for the pairing session. Examples:
Either person can take a break at any time, requiring no reason to do so
Both people have easy access to a shared whiteboard (e.g. Miro) that is kept handy to facilitate discussions
The pair uses a timer to enforce (or only consider) regular:
breaks
swapping of roles
check-ins
Navigator has something to do
The primary responsibility of the Navigator is to think multiple steps ahead. But what does that actually mean? Here are some examples that I’ve experienced where the Navigator role was effective:
While the Driver works through an experimental refactor, the Navigator identifies and takes notes on refactoring alternatives that have not been discussed yet
While the Driver attempts one fix to a bug, the Navigator notes down other potential fixes
While the Driver implements the initial algorithm that was agreed upon, the Navigator realizes an edge case that the algorithm does not cover and notes it down
While the Driver sequentially works through implementation of a series of specification examples, the Navigator identifies emerging design patterns in the growing codebase and notes them down
Notice that in all four examples, the Navigator takes notes of their ideas and observations. This is deliberate. The Navigator should avoid speaking these out-loud to the Driver while they are in the middle of driving (i.e. coding). That might not mean typing — it could mean a brief moment of silence while they think about the next move. The key point here is to avoid interrupting the Driver’s flow. Wait for the next break (induced by the Driver or by the timer) to review and discuss the Navigator’s notes.
Avoiding Anti-Patterns
There are plenty of Driver-Navigator anti-patterns; they are written about elsewhere at great length, so I will only provide a brief overview. Here are a few examples:
Driver-Twitterer: Navigator stops paying attention to what the Driver is doing, and instead goes on Twitter. Or Slack. Or Jira. The point is, it stops being a pair programming session when the Navigator is no longer engaged.
Backseat Driver: Navigator dictates specific instructions to the Driver, e.g. “ do this, now do this, now this…”. Ironically, this anti-pattern is very similar to strong-style pairing. The key difference being that the anti-pattern occurs when Driver expects to have control2.
Fighting for the keyboard: Navigator has an idea, but instead of noting it down, says, “here, give me the keyboard, let me try something…”. A number of keystrokes later, the other programmer says “wait, I have a better idea…” and does the same thing. In addition to being unpleasant, this anti-pattern can lead to plenty of half-baked ideas, with precious-few fully-baked ones being earnestly explored, let alone implemented.
In case you haven’t noticed already, these anti-patterns arise when the Navigator doesn’t understand their role, when they don’t have something to do, or both. Generally, the Navigator taking control from the Driver is not an effective move, because once that happens the new Navigator is relegated to observing passively (as opposed to navigating actively). Instead, it’s best to wait until the Driver is ready to give up control. At this point, the pair can decide if the Navigator has something to do. If not, then an alternate pairing style (such as ping-pong or strong-style) can always be considered.
Wrap-up
Given how misunderstood Pair Programming is in general, it’s no surprise that misunderstanding Driver-Navigator is also common. Having a shared understanding of Driver-Navigator, what the pairing style requires, and an appreciation of alternative pairing styles, can go a long way in ensuring an effective pairing session.
Working agreements are typically set on the product-team-level. Given that a pair is essentially a team of two, pair programming is another opportunity to experiment with a lightweight working agreement that lasts only for the duration of the pairing session.
“Control” is one of a few pair programming themes that I explore in an earlier post.