Here are a few things we've learned over the years which have helped us be more pragmatic and more practical in our application of pairing.
In Part 1: Pairing is not Always Practical, we explained how the costs of pair programing sometimes outweigh the benefits. Here are a few things we've learned over the years which have helped us be more pragmatic and more practical in our application of pairing:
- Realize that not everything is pair worthy
- Discuss each card upfront
- Short feedback loops are essential
- Code reviews are a must
- Speak up! Developing software is no time to be timid
- Pairing is not just two bodies, one computer
- Watch out for passive pairing
- It's okay to work alone
Realize that not everything is pair worthy
Let's face it, not everything is pair worthy. While some cards certainly require full-on pairing, there are cards or parts of cards which certainly do not. Pairing for a card that does not require it is an irresponsible use of the limited resources we have been given to work with. This hinges on what definition of pair-worthy we're working with. So who determines what's pair worthy? The team does.
Being honest about what cards are and aren't pair worthy provides the ability to identify new strategies for maximizing value and minimizing risk while continuing to swiftly and confidently progress forward.
Discuss each card upfront
Having a short discussion on each card with your pairing prospect can help identify the confidence and risk you both have in understanding the card and in implementing it.
When you and your pair are confident and experienced in both of these areas it's a likely indicator that working separately is appropriate. This is because the risk is low and the potential value of pairing is low. On the contrary, if someone isn't as familiar with the problem or the implementation, then it may be a great candidate to pair and transfer valuable knowledge.
It's also important to note that these discussions are typically more in depth than what was talked about as a team when estimating the card originally.
Short feedback loops are essential
One of greatest aspects of pairing is the extremely tight feedback loop. As you code, your pair is immediately able to review the direction you're heading. If you need to stop and discuss you can do so without further delay; then quickly begin again. Compare this to working in silos where it can be difficult to know when you're in a rut until too much time has gone by.
Fortunately, rabbit trails are easy maneuver around and avoid. Here's how: after you've discussed each card and determined that working separately makes sense, routinely check with one another. When everything goes as planned this will take a couple minutes to do, afterwards you can continue to move forward confidently. In the case that something unexpected came up, you're able to re-evaluate where you're at, decide whether pairing at this point makes sense, and discuss how to best handle the remainder of the card.
While not as tight as the feedback loop in a pairing session, implementing a short feedback loop when you work separately is a simple way to continue to have the valuable dialogue which you'd otherwise have to pair to have.
Code reviews are a must
No card should be considered finished without a code review. Whether you wait until the end of a small card or you review during your short feedback loops, it's sound judgement to have a peer review your code. This helps keep your code well-factored, well tested, and ready for production by allowing another human being look it over, ask questions, and make suggestions.
Speak up! Software is no time to be timid
The other week I was working on a card which seemed simple enough; I was updating a SOLR query to exclude blank values for a particular field. Updating the SOLR query was a piece of cake, but I found legacy code in the mix which made it very awkward to introduce the change in a clean, testable way. It had nothing do with the query, but how the class containing the query was being used. I spent a few minutes trying to look at the code in multiple different ways. I came up with a few solutions, each requiring shotgun surgery, none amiable to the surrounding code.
Had I moved forward with one of my solutions I would likely still be working on that card. Thankfully that card is done and it was done shortly after I hit the challenge of the legacy code. I decided to speak up and get with Chris to review the code with me. He came up with an idea that I hadn't thought of. It improved the code and introduced testability in a pleasant way with a minor refactoring to the existing code. No shotgun surgery needed!
The moral of this story is that you can be confident in your ability to solve a problem and you may be able to solve it, but always be humble enough to speak up and seek input from others. Doing this will give you the opportunity to have the thoughtful discussions that you'd normally have with traditional pairing, but in effect you'll be doing partial pairing.
Pairing is not just two bodies, one computer
Pairing done well is greater than the sum of its parts. You can have a two people at one computer and still end up making bad decisions and producing crappy code at an exorbitant price. Pairing requires active participation from both people. It's a social activity meant to spur discussion, better decisions, and opportunities to learn and grow. It also takes a lot of energy to do, so if you or your pair are feeling a bit exhausted don't be afraid to take a break and work independently. After all, solitude can be a good thing.
Watch out for passive pairing
Have you ever been pairing when your brain kept floating away from the task at hand, or perhaps you were driving and your pair was sitting next to you but not really participating? If so, you've been in a passive pairing session. If you haven't, don't worry, you will. It's not so much a matter of if, but of when.
Passive pairing looks like pairing, but it really isn't. It's really just having an extra body by the computer. Passive pairing can be a result of the card you're working on not really being a pair-worthy card, someone driving too long, someone being burnt out or exhausted from pairing, or the signs you just need to take a break (among other things). If you identify yourself in a passive pairing situation, re-evaluate with your pair the current direction and don't be afraid to change drivers, take a break, or work independently for a while.
It's okay to work alone
As valuable and rewarding as pairing can be it can be equally as valuable and rewarding to work alone. It let's our brains work through problems, solidify knowledge of things we have learned, and challenge ourselves in ways that we find rewarding. Both working in solitude and in collaboration -- whether pairing or another means -- allow us to grow individually and as a team. Having both sets of opportunities available is something I believe is important for being a well-balanced team.
Pair programming can be an extremely valuable tool in our toolbox, but it can also be an extremely costly one. When the value provided outweighs the cost we should use it, but when it's the other way around we should consider other strategies for maximizing value while minimizing risk. This is just another part of what it means to be software craftsmen, not only to produce and deliver quality software in a sustainable way, but to be good stewards of the limited resources we're given to work within. Being purposive and reflective in our application of pairing helps us wield it judiciously.
Intentionally pairing or choosing to not pair actively shows that we have a continually better understanding of our craft and healthy respect of our clients. Without clear intent, we're merely hoping that pairing is going to pay off at some point in the future, and while wishful thinking is a strategy, it's not one you'll find in my toolbox.