You are on page 1of 8

Popularized by Extreme Programming enthusiasts a couple of decades ago, the act of

programming together with another developer on the same workstation gained massive
adoption within ThoughtWorks. Nowadays, Pair Programming is seen as an effective way to
keep our folks happy, productive and learning, as is described in the article.
As with any widely adopted practice, there are quite a few variations in style and technique.
In this article, wed like to focus on the most common style in use at ThoughtWorks currently:
two programmers physically share a workstation, with a single view of the desktop (either in
one monitor or with two mirrored screens).

In that style, actively sharing the input devices can be problematic: except for a few
multiplayer games, its hard to find software out there that supports two people typing and
clicking around at the same time. To avoid confusion and unnecessary use of the backspace
key, pairs naturally agree on who gets to use the keyboard and mouse at any given time, and
those arrangements can vary widely depending on a number of factors.

To us, an extremely important part of such agreements is what to do when a programmer is


not typing. The term navigator (as the opposite of driver), used to describe that role,
likely comes from rallying where its usual to have a navigator sitting next to the pilot or
driver handing out coordinates and calling attention to troublesome spots along the way.
Much like in racing though, the driver gets a disproportionate share of the credit and attention,
and often, the mechanics of good navigation have been somewhat neglected.

What is a Good Navigator Concerned About?


A Clean and Safe Environment
First things first: basic etiquette of sharing a physical and a virtual working space with another
person should apply, and the pair should be responsible for ensuring, before a programming
session starts, that the working area is clean and comfortable for both individuals.
They should avoid any unnecessary noise or smell and respect each others personal space.
Additionally, theres a need to consider a healthy number of breaks during the day, as
tiredness can develop more quickly due to the more active communication that pair
programming usually demands.
A Consistent Environment
With a clean physical area to work on, the pair should also ensure the virtual workspace is
taken care of to avoid introducing unnecessary environment-related distractions. Any
unrelated work is cleared, at least visibly, and the workstation is configured consistent with
other development environments and meets the expectations of both developers.
Editor settings and dotfiles can be easily shared across with the team and kept under source
control, but its worth paying attention to other things like font sizes, screen resolution, other
running applications and pop-up notification settings that might creep up and become
distractions. Navigators should have free reign to remind over-enthusiastic drivers changing
those, and of the benefits and trade-offs of consistency against personal preference.

Mapping the Course


Before the programming starts, its important for the navigator to ensure their pair knows and
is able to clearly state the goals they are headed towards. Getting to that state might involve
discussing details of a story or task with product or technical leaders of the project, and
breaking down any larger items into bite-sized chunks. Usually, pairs will do that together at
the beginning, and the navigator takes the responsibility of keeping a goal stack up-to-date
as the work progresses:

Working with a stack has another advantage: while thinking through the tasks needed to
complete the programming session, the navigator has to flip between thinking backwards (in
what state do we want to leave this system in?) and forwards (what do we need to do to get to
the next step?), and we find that a stack lends itself to that kind of back-and-forth quite
naturally.
Reviewing the changes needed to the code usually leads to more items and detail to be added
to the stack. Sequencing and prioritizing that work effectively requires some practice, in
particular when balancing the stack: ensuring any chances to do opportunistic refactoring are
taken into consideration while ensuring to not take on too much additional work.
In some teams, pre-flight checklists are put at the top of the goal stack: before work begins,
some pre-defined tasks have to take place like moving the card referring to that story in a
Kanban wall, creating a feature toggle or branch, or refreshing a local copy of a production
database are recurring examples. Similarly, post-flight checklists might require developers to
move the card again, do a desk-check with product and technical leaders, demo the
functionality to a user, etc.

Course Correction
As they go through the goal stack, driver and navigator will eventually detour into some
unknown part of the system, or a corner case in the acceptance criteria of the functionality. At
these points, a navigator has to be conscious of their role in ensuring the pair is going through
the planned tasks or readjust the plan accordingly.
While its acceptable to leave some unknowns or dirt behind in order to get the job done, a
good navigator knows when to say not right now. To that effect, multiple funny-looking
acronyms have been created like DTSTTCPW, KISS, YAGNI and so on.
These acronyms may even be used as the navigator as commands, analogous to the rally
navigator who says stay to the left, 300 metres or a well-placed and thought through you
aint gonna need it, when discussing bringing in a third-party library for example, can stop a
lot of unnecessary stress. A good navigator, freed from dealing with the mechanics of driving,
should be able to spot those moments and see pitfalls coming from further away than the
driver. That is not to say that the opinion of the driver shouldnt count, of course it should.
Negotiating these decisions is a job for both the driver and navigator, but ultimately the
responsibility for doing it effectively and pragmatically lies with the latter.
Another common command a navigator might use is lets start with a test for this. It
might seem mundane at first, but we found that when the navigator takes responsibility for
keeping the TDD cycle in check, the red-green-refactor cycle becomes a more fluid
experience.

Clearly Communicating Intent


Its easy for novice navigators, even more so those who are seasoned programmers, to get
carried away into treating the driver as an order-taker or IDE operator with no particularly
good judgment of whats going on. This undermines the value of pair programming, as the
point is to make joint design and implementation decisions, which is best avoided.

Still, sometimes the driver gets stuck on how to proceed on a less abstract problem like issues
with an unfamiliar tool, language or API pop up rather frequently. A trap many well-meaning
but less experienced navigators fall into fairly often is to offer up advice as soon as that
happens. Good navigators know when to wait a little bit before pointing out a missing
semicolon somewhere, and will do it when theres a natural pause in the driving. A very large
number of interruptions rising from unfamiliarity of the driver might be a good indication that
its time to swap roles, even if for a very short amount of time.
For all the more interesting and more abstract issues, though, an experienced navigator is
good at communicating intent the what, not the how, and uses inclusive language (us and
we, rather than I or you) as much as possible while at it, so the driver is invited to
revisit some of the motivations behind intents they might not necessarily agree on.

Even when intent has been communicated clearly, we find that explicitly asking for
confirmation is a good practice as it validates understanding and opens the conversation to
feedback from the driver.

Visualizing the Course


Another set of tools a navigator has at their disposal in this regard is the plain old pen.
Drawing and sketching are some of the best ways to show someone what a path might look
like.
Pseudocode
Some algorithms and data structures can be a little unclear in UML. Pseudocode is usually
most employed when discussing small parts of the code like a caching strategy
implementation, but can be useful at the beginning of a programming session, when creating
the goal stack. At that point, each line of pseudocode could thought of as an item in the
stack.
Boxes and Arrows
Most systems will have their features implemented following a consistent architectural
pattern. In a typical database-backed web application, for example, many of the features can
be explained by adding in some more detail to the following diagram:

Jotting down this diagram on a piece of paper large enough to accommodate new
collaborating boxes and changes to arrowheads can be a good way for a pair to start thinking
about the current state of the system, or which modifications and additions are needed.
Sketch UML and UI

Though it has somewhat fallen out of flavor, UML is an excellent way to describe systems in
a visual manner. We prefer to use UML as a sketch while explaining a class hierarchy or set of
interactions between systems.
Forward and reverse engineering are equally well served by sketching some UML. Being able
to erase parts of a whiteboard selectively can be useful in detailing the steps of a larger
refactoring, for example.

At ThoughtWorks
We find Pair Programming to be one of the most effective ways to keep our developers
productive, sharing knowledge and experience. It has certainly helped us build strong teams,
reduce our defect rate and keep people happy. It is important to remember that both roles in
the pair are equally important with specific expectations and responsibilities during pairing.
Also, neither driver or navigator responsibilities last forever; it is encouraged to change roles
several times during the course of a pairing session, and both wheels have to be in good
shape.

You might also like