Pairing: how to increase quality and how to halve learning

I have mixed views on pair programming. While I think it’s absolutely great for increasing code quality (used with TDD even more so), I also think it’s a lazy way to share knowledge and can ultimately halve your organisation’s ability to improve its knowledge.

Halving Learning

Pairing is not a good way to transfer knowledge and will not increase the speed at which you learn. Put another way, pair programming is an absolutely terrible way to transfer knowledge and a guaranteed way to halve your organisation’s capacity to learn.

I’m huge on learning. I believe that at least 80% of software development is about learning. Great programmers are people that can figure stuff out. Average programmers can’t. Figuring stuff out requires practice. You have to exercise discipline, tenacity, time management, a good balance of creativity and logic, a meticulous eye for detail, the ability for lateral thinking, a thirst for knowledge, and a ruthless drive to improve.

The first time I tackle a problem most of the time is spent learning. For a typical day of programming, if it was a non-routine problem (of which most of ours are non-routine) it can usually be rewritten in an hour or less once you know the solution. Have you ever seen a developer that types constantly? No. Developers are mostly thinking or researching in order to work through their current problem. At most 20% is probably spent coding up their solution. If this isn’t the case, it probably means you’re doing something pretty routine that isn’t problem solving or you’re trying to program by coincidence.

When I’m in problem solving mode, I would probably learn more slowly if I had to pair program. I learn fastest without distraction where I can work at my own pace. I need focus to think. I don’t get distracted by having to explain the things I already know won’t work and I can try out things without debate. This way I can learn first hand what works and what doesn’t gaining valuable first hand experience.

Once I’ve figured out what works, it will take a fraction of the time to summaries to a colleague what worked, what didn’t work, what I left untried, and what knowledge I was building upon. Developers can exchange this information quickly. The closest I would suggest people get to pair programming when in problem solving mode is to independently trying to solve the problem and compare their findings at the end. This has the benefit of avoiding either person getting polarized by the other’s idea during the creative problem solving process.

You should recognize when you’re in quality mode and when your in learning mode and switch up your style of programming appropriately. This may be many times a day.

Learning time will usually out weigh your coding by 5 times. In order to facilitate the knowledge hand over you can capture some types of learning as tests, other types of learning as notes or diagrams, and other types of learning as clear code that is self explanatory.

First hand learning is the quickest way to deeper understand, increased self confidence to tackle more complex problems independently, and increased mastery of software development in general.

Work, Rework and Maintenance in Software

I thought it would be worth clarifying the terminology used to express the different types of work, rework and maintenance in software development.


Refactoring is the art of making your code clean and refining the design in small incremental steps towards the SOLID principles of software development. Refactoring should be performed many times a day to ensure code is clean.


In order to learn enough about a problem, a prototype is often built that will be thrown away. If the prototype is not thrown away, it is not a prototype. Prototyping should be used to gain knowledge and understanding of a problem. A prototype will generally have a substandard design because the problem is not well understood until the prototype is finished. That’s why you throw a prototype away and redesign what you have just done with increased knowledge. Don’t continue working on a prototype when there is no more learning taking place. Do not mix user interface prototyping with software design prototyping. Always keep the two separate.

Tracer Bullet

A tracer bullet is an implementation of part of a piece of software. A tracer bullet is used to learn enough about the larger piece of software, usually in order to inform estimates and tackle technical risks early. Tracer bullets are risk management for developers. A tracer bullet is only finished if the code is production ready, tested and has been kept clean by constantly refactoring the code during development otherwise it is a prototype and should be thrown away.


Redesign is usually undertaken when existing code needs to be drastically remodeled. Redesign is an indication of one or more of the following problems:

  • the code is not clean and does not following the SOLID principles
  • there was inadequate knowledge during development
  • the project was rushed
  • technical risks were not properly flushed out

Redesign is caused by a lack of refactoring, prototyping and tracer bullets.


Every project should have a healthy mix of prototyping to inform design, tracer bullets to inform estimates and reduce risks and refactoring that should be done regularly throughout the day. Redesign implies that you’ve got an unhealthy mix or are ignoring important steps in the software development cycle.

Also, changes to requirements would potentially precipitate one or more of refactoring, prototyping, tracer bullets, or even redesign. The later suggesting quite a major change.