The Process

This style is actually very close to an actual navigator / driver situation in a car or on a boat. With all the high level commands coming from the navigator and the lower level implementation happening from the driver.

This style of programming is all about increasing communication and collaboration. Verbally communicating code and editor commands is a skill like anything else but it is one that many people have not developed yet. Don't worry, it's pretty easy to gain and most people pick it up the basics in a few hours.

The Driver

As a driver (at the keyboard) this is a fairly simple and peaceful place to be. I have been the driver in languages and editors I was completely unfamiliar with without problem or incident. However, there are two important things that are required for a happy driver experience.

"Trust your navigator"

When you are the driver trust that your navigator knows what they are telling you. If you don't understand what they are telling you ask questions, but if you don't understand why they are telling you something don't worry about it until you've finished the method or section of code. The right time to discuss and challenge design decisions is after the solution is out of the navigators head or when the navigator is confused and unable to navigate.

"Become comfortable working with incomplete understanding"

Even if you trust the navigator, the navigator might not be comfortable navigating you in this strong style. To combat this they might try to explain everything to you before you can actually start to code. This slows things down a lot and depending on your level of knowledge can taking hours or even days before you can even start. Don't worry about knowing everything, you will learn as you go. Don't worry about not knowing stuff. You might not know the language, os, editor, code, or even the problem space you are working in. It's ok, you will soon.

"What if I have an idea I want to implement?"

Great! Switch places and become the navigator.

The Navigator

As the navigator you have two main jobs.

Give the next instruction to the driver the instant they are ready to implement it

Talk in the highest level of abstraction the driver can understand

The navigator is essentially managing a ToDo list in their heads. As you go through the code you keep adding things to the list and as the driver is typing you keep removing the completed items from the list. The key is while you are handling and tracking 2-20 things at a time, the driver is only ever responsible for 1 thing. This is the key to letting the driver stay in a state of flow. This is the number one main job for the navigator; Manage the big picture details so the driver can stay focused on the code they are typing.

The second job of the navigator is to speak at the highest level of abstraction that the driver is able to digest at the moment. This will change by driver, of course, but it will also change during the day for the same driver.

For example, a navigator might tell the the driver "extract that method" to which they might get a blank stare. The navigator should then restate that intention at a low level of abstraction. Such as "ctrl+alt+m" or even "highlight lines 14-20 and then press ctrl+alt+m". After doing that a few times the navigator should be able to revert back to the higher level of "extract that method" but always realize that later the driver might be tired or just plain forgetful, adjust accordingly.

It is the navigators responsibility to communicate in a meaningful way. This means you shouldn't be speaking above the drivers understanding. However, it is also the navigators responsibility to be ever increasing the the level of communication and understanding. Stay mindful of the driver and be constantly adjusting to them.

"Just do it"

Although you are the navigator, you are going to make mistakes and bad decisions. Correct them when you do but don't sit around and plan to try to avoid. When someone has an idea have them take the navigator role and go. once it's out look back with the benefit of hindsight and refactor or redo it so it's better.

The Mouse

When there are just two people, I find that often the navigator will end up with their hand on the mouse. This tend to work well when the activity is much more keyboard focused (like programing). It is horrible if you are doing something more mouse focused such as graphics or installs.

Common problems with pairing

The main reason I use this method of pairing is it solves many of the common problems I see occurring with pair programming. Here are a few of the problems and how this style of pairing addresses them.

1 person working and 1 watching

If your navigator isn't engaged then you really are not even pairing. Traditional pairing makes it unfortunately easy for the person not at the keyboard to zone out and disengage. This is literally impossible with the strong pairing style as the only way for that to happen is for both people to be doing nothing.

Fighting over the keyboard

Different people might have different ideas on how to implement something. While this still happens with strong pairing style it changes from wanting to grab the keyboard and shut out the other person to wanting to let go of the keyboard and then communicate your idea to the other person.

Expert/Novice Pairing

One part of pairing that is often highlighted as a problem is the Expert/Novice combination. You can imagine that watching someone fly through pages of code when you are unfamiliar with the language, editor or even the business domain would be hard enough to follow let alone to contribute. With the strong style of pairing, however, this becomes an very valuable combination to both the expert and the novice. In this style, the expert almost always is in the navigator position having everything go through the novice. This is a very intense way of immersion learning. I am often surprised to find how quickly I can achieve basic fluency in a language or business domain, usually within a few hours or days of being the driver.

But what about the Expert? The expert also benefits. First they are not slowed down by the presence of the novice. This is a big deal as it can be the main issue that prevents the two working together and also prevents them eventually becoming equals. The expert also benefits from being able to think at a higher level in the role of the navigator. Just as it is harder to look at a map and keep your eyes on the road as you drive a car, it is equally hard to look at the big picture problem you are solving and type the individual letters needed to make compiling code. Finally, the expert benefits greatly from interacting with the 'beginner mindset'. You might have heard the saying "to really learn something, teach it" and some of my most profound insights have come when a novice has simply asked me "Why?"

What are you thinking?

If the thinking is happening in the same person that is typing then they usually are not talking. This means that you are supposed to guess what they are thinking through some sort of reverse engineering of the code that is appearing on the screen. By making the navigator speak out loud, you help to ensure that everyone is on the same page. However, this is only the start of the benefit to talking out loud. A different part of the brain is used to talk than to type. When you say something out loud a small amount of improvement occurs between your brain and your mouth (I often wish it was greater :-) There is an other level of autocorrect that occurs when it is received by the other person (I frequently find myself thanking my driver for understanding what I meant instead of what I said) but there is also a sort of 'stupid trap' where the very bad or unformed ideas are not able to bridge the gap between the navigator & driver and get flushed out because of it. Finally, there is a checksum when the navigator sees the code end up on the screen. Because the navigator now has an expectation of what 'should' be appearing, so they are in a position to actually review that that it is what was wanted.

Just in time thinking

When the navigator gives a direction, they might not know the full path of where to go. In fact, the vast majority of the time I navigate, I do not know the path or even the final destination only the next step. While the driver is implementing the current step, I have time to figure out the next step. In this manner, the navigator can stay one step ahead of the driver the whole time.

Side Note: While this is very practical for production coding, it can sometimes lead to the misconception that the navigator knew what they were doing all the time but just didn't want to share it with the driver ahead of time.

Final thoughts

This method of pairing has been very powerful for me and is the main way I have been pair programming for the last 11 years. It is very effective, fast, and efficient. However, it can be very 'strong' as the name implies. Here are a few helpful tips I have picked up over the years to help soften it.

'Ask for trust'

Sometimes the navigator and the driver will butt heads. I have often made the mistake of trying to argue the merits of my ideas when the actual problem is that the driver does not trust me. If you don't trust someone, all the logic in the world isn't going to help. A simple solution to this is simply to ask for a temporary window of trust. For example:

"I know this seems wrong, but could you please trust me for 4 minutes

and then we will talk about the solution and remove it if you aren't happy"

After you get the code out there, you both will be in a place where you can now talk about the merits of it. Of course, this doesn't mean you are right, you might find yourself deleting the code you just wrote, but it is faster to ask for trust, program for 4 minutes, and then delete it than to argue for 30 minutes to avoid ever having to write it the wrong way.

Take breaks to reflect and explain

Pomodoro's (25 minutes of code then 5 minutes walking around the block talking) can be a great way to lower the intensity of this style of pairing while increasing the shared insights and learning.

More importantly, always keep an eye out for the driver to make sure they get proper time to understand the high level picture as well. After you finish a section, it can be good to stop and retrospect what just happened and ask questions.

If you are in a situation where the driver/navigator roles don't seem to change very often, it can also be good to force the roles to switch. In the short term, this will slow production, but it will make for a more well rounded team and have profound long term advantages.

Sunday, June 8, 2014

A lot of the conversation around removing duplication goes something along the lines:

"remove duplication"

The idea is there is a a scale and your code should be on the low duplication side of it.

Unfortunately, this is only half the story. There is a hidden, often forgotten, label that belongs on this scale: Cohesion

The rule you want to follow is this:

Choose the lowest duplication for the natural cohesion

Examples of low cohesion

My last name is 'Falco'. My sister's last name is also 'Falco'. This is duplication, but there is no cohesion between the names. If my sister marries and changes her name, my name should not change as well.

Because of the low cohesion between our two names, it should have high duplication.

Many unit test scenarios fall into this area, which is one reason you might end up with higher duplication in your test code.

Examples of high cohesion

An advantage of working in many PHP systems is that no matter what I do to a page the worst I can do is mess up that single page. PHP systems tend to have high duplication. The down side of this is when something changes, for example: how sales tax is calculated on a page. Sales tax has high cohesion, I don't want it to be different for each page. This means that when I need to change it I have to go to all the different pages that implement it and change them. The biggest problem is that most likely means I will forget one of the pages.

Detecting Cohesion via Source Control

You are looking at your source control and discover that in January five files all changed in a single checkin. Those same 5 files all changed together in February as well.

March - Those 5 files changed together

April - Those 5 files changed together

May - Only 4 files changed together

June - Those 5 files changed together

What happened in May?

Yes, someone introduced a bug.

Think about that from a bug detection point of view. You didn't test, you didn't even know what the expected user behavior was, you certainly didn't look at the code. You just detected a natural cohesion and noted that a change was missed in 1 place. This is why you want the minimal duplication for the cohesion that is naturally existing. If everything thing that needs to change together is only in 1 place, you can not forget the other places.

TL&DR; If you have things that need to change together duplicated you have too much duplication. However, if you've removed duplication on similar things that don't change together you will have problems when you change one of them.

Some time ago Kent Beck observed that there was a pattern for simple design

Runs all the tests

No duplication

Expressess developer intent

Minimizes the number of classes and methods

There has been some debate over the ordering of #2 & #3. Of course, this is just a observation of a pattern ordered by preference, personal preference, so it makes sense that you might have your own preference. But...

"What is your personal preference?"

It seems like that should be easy enough to determine, just ask yourself, but here's the rub:

cognitive scientist & economist have long observed that there is a great difference between

Stated values: what we say.

Demonstrated values: what we actually do.

If we just ask people we will only get the stated values, to get what they actually preference we need to see what they do in action. For that we need a test.

Removing Duplication Test

Take a look at the following:

Let's remove the duplication. Just circle the duplication that you would like to remove then scroll down to see what your individual preferences are.

Answer #1

If your answer looked like this:

You would probably written a piece of code like this:

iLike("fishing", "biking", "playing", "swimming", "sleeping");

and you have demonstrated a preference for: #2 Expressive Code over #3 No Duplication

Answer #2

If your answer looked like this:

You would probably written a piece of code like this:

iLike("fish", "bik", "play", "swimm", "sleep");

and you have demonstrated a preference for: #2 No Duplication over #3 Expressive Code