Pairing for Beginners (and Skeptics)
My shop is about to introduce more pair programming into our daily development routine. Here’s a more or less “braindump” on my pair programming experiences. I can’t say I like everything about pairing or always enjoy it, but overall the benefits I’ve seen are real enough to make me a believer. I’m the exact profile (introverted, used to working solo) of the guy who will have trouble doing pair programming and I can still do it, so it’ll surely be easier for you.
“This is the Way We Do It”
My favorite metaphor for software design these days is a fishing tackle box. I want a place for everything and everything in its place. When I need a top water lure, I know exactly where to look. I put data access code here, business logic there, and hook the two things up like this. When I’m creating new code I want to organize it along a predictable structure that anyone else on the project will instantly recognize. When other coders are making changes I want them to follow the same basic organization so I can find and understand their code later.
Each application is a little bit different so the application’s design is always going to vary. In any agile project you should hit an inflection point in the team’s velocity that I think of as the “This is the Way We Do It” moment. Things become smoother. There are fewer surprises. Story estimates become more consistent and accurate. When any pair starts a new story, they understand the general pattern of the system structure and can make the mechanical implementation with minimal fuss.
You really want to get to this point as soon as you can. There are two separate issues to address before you can reach this inflection point.
- Determining the pattern and architecture for the system under development
- Socializing the design throughout the development team
To the first point, pairing allows you bring to bear the knowledge and experience of everybody on the team to the work at hand. It’s just not possible for any one developer to understand every technology and design pattern in the world. By having every developer active in the project design, you can often work out a workable approach faster than a solo architect ever could. On the one project I’ve done with theoretical 100% pairing, we had a couple of developers with a lot of heavy client experience and me with more backend and web development experience. By pairing together with our disparate knowledge we could rapidly create a workable general design strategy for the system as a whole by bringing a wider skill set to any coding task.
As an example from my short stint on an architecture team, I saw one of my architect peers design an elaborate solution for an ETL (Extract, Transform, Load) infrastructure between several systems with an absurdly complex error handling subsystem. We had a site license for Sql Server and every single thing he designed could have been accomplished out of the box with Data Transformation Services in Sql Server instead of his custom design. If he’d been listening to or working with the other developers they could have solved the ETL issue quickly and spent more time on the infrastructure management aspect of the project to create a design that the developers could actually code.
If you’re a senior developer or the technical lead, one of your responsibilities is fostering an understanding of the technical direction to the other developers. Nothing else I’ve ever done as a lead (design sessions, documentation, presentations, “do this,” etc.) beats working shoulder to shoulder with other developers as a mechanism for creating a shared understanding of the project strategy. By making every developer be involved or at least exposed to the thinking behind the design, they’ll have much more contextual information about the design.
One unpleasant fact I’ve discovered over and over again is that the more detailed instructions you give to another developer, the worse the code is that comes back to you. I simply can’t do the thinking for someone else. If the developer understands the “why” of the design, they always seem to do a better job and often make improvements as they go.
For example, my wife routinely organizes our large CD collection. She promptly becomes angry with me when I put CD’s in the wrong place because I don’t understand her organization rules. I don’t understand why the CD’s are on what shelf because I had no part in creating the organization. After 9 years, I still don’t understand how my wife thinks either, but that’s a different problem.
Improving Our Code vs. Defensiveness about My Code
Don’t for one second discount the psychological advantages of pair programming. Formal or even just peer code reviews can be nasty affairs. They can often amount to a divide between the prosecution and the accused. In my admittedly limited experience, they’ve been largely blown off or devolve into meaningless compliance checks with coding style standards. Even worse is the fact that they are generally used as a gating process just prior to the next stage of the waterfall, eliminating the usefulness because it’s too late to make any kind of big change.
The collective ownership achieved with pair programming can turn this situation on its head. My peers and I can now start to talk about how to improve our code instead of being defensive or sensitive to criticism about my code. Since we’ve all got visibility now into the majority of the code, we can have informed conversations about the technical direction overall. The in depth code review happens in real time, so problems are caught sooner. Add in the shifting of different coders through different areas of the code and you end up with more eyes on any important piece of code. The ability to be self-critical about existing code, without feeling defensive, helps to continuously improve the system design and code. I think this is one of the primary ways in which agile development can lead to a better, more pleasant workplace.