Tuesday, August 30, 2011

Life After Pair Programming

When I first joined DRW I noticed that the vast majority of developers were not pair-programming. I was surprised that a company that employed so many smart people would just simply disregard a practice that I considered to be so obviously beneficial.
note: it's so easy to judge people who don't pair-program, isn't it? You can write-off their behavior for so many reasons:
  • They simply haven't done it enough to see how much value it provides.
  • They've used the wrong setup, and turned a positive ROI into a negative ROI situation in the past.
  • They must be anti-social or not team players.
  • They must guard their code because they are too proud or believe it's job security.
Never once did I consider that their behavior might be correct based on their context. There was no context in which pair-programming wasn't the right choice, right?
So, I did what any responsible employee who wants to help would do: I gave a presentation. I took pictures of a traditional (read: broken) pairing station setup - the setup where one employee looked over the shoulder of the person doing all the work. Then I took a picture of a dual monitor, dual keyboard, and dual mouse setup. I made the distinction between pairing and watching someone work. I explained how ping-pong-pair-programming worked. I think I said the right things, and the presentation was well received. Management was on board and offered to setup pairing stations for any developers in the company that wanted to give it a try.

A few people embraced it, but most went back to their traditional habits. I did manage to convert the guys on my team, and we paired the vast majority of the time.

Almost 3 years later, and on a different team, I basically never pair. In fact, when my lone teammate (and boss) asks if we should pair on something my initial reaction is always 'no'. The 2 of us are the only people working on the applications we support, and when we pair I often find myself very distracted and not really participating. Sometimes we ping-pong-pair and it keeps us both involved, but I don't feel like we're going faster than if I'd been working solo. Don't get me wrong, we sit directly next to each-other, talk constantly, and even look at code together at times when we're just starting to talk about a new problem. That level of collaboration feels beneficial, but actually coding the implementation together feels wasteful.

I know how I felt 3 years ago (when I joined DRW), and I know how I feel now. The fact that I've changed my tune so drastically made me think it was worth putting a few ideas on the web. I was also motivated a bit by the recent publication of Pair Programming Benefits. The Pair Programming Benefits article actually gives me a perfect starting place, by examining the benefits of pairing and how they apply to my context.

I feel like I can safely summarize the Team and System Benefits as: transfer of knowledge, superior quality, and collaboration. The Programmer Benefits can be summarized as: expansion of knowledge, truck factor reduction, superior quality, and team support. The Management/Project Management Benefits can be summarized as: aiding addition and removal of employees, knowledge transfer, and the ability to hire any skilled generalist.

So, our full list of benefits is: expansion and transfer of knowledge, superior quality, collaboration, truck factor reduction, team support, eased hiring and firing. I would agree with these benefits of pair-programming, which explains why I was such an avid believer in pairing in the past. However, if those pros don't apply to my situation then pair-programming becomes nothing more than using twice as many man hours to get the same amount of work done.

I'll start by addressing the easiest "benefits" that are effectively irrelevant for my team: eased hiring and firing and truck factor. Like I said before, my team size is 2. Mike and I are both very happy and there's almost no chance that either of us leave anytime soon. Even if we did choose to leave, we would give enough notice that someone could easily come in and replace us - and either one of us could support the applications on our own if necessary. The only real risk is that we both are killed at the same time - at which point it wouldn't matter if we paired or not. Statistically it's much more likely that only one of us would suffer something causing us to not be able to return to work, and as Chris Zuehlke (manager at DRW) once pointed out to me: if you build small, well written processes the time to understand or rewrite any software you know nothing about is small - often smaller than the cost of keeping 2 people informed on the details of the process. If I asked the stakeholders if we should use 2x as many man hours to ensure that we're covered in case one of us is suddenly killed they'd laugh at me - and I'd deserve it.

We're also not looking to add to our team, and if we decided we did want to grow I expect we wouldn't have any trouble finding someone who was looking for a well-paying job in manhattan using very cool technology.

The previous discussion was meant to address team size, but it also touches on "transfer of knowledge". Transfer of knowledge is valuable for teaching new techniques and enabling people to do maintenance. However, if little teaching is going on (often the case as Mike and I add features to an app we know fairly well, using technologies we know fairly well) and we both tend to do the maintenance on the code we previously wrote then "transfer of knowledge" is either not occurring anyway or is unnecessary. Also, on more than one occasion I've had to take a first look at some code Mike had recently written. It's always been straightforward and taken no more than an hour to dig-in, make, and test a change. Had we paired on everything he worked on I would have unquestionably spent far more than an hour here or there. Again, the ROI on knowledge transfer doesn't look good for our situation.

The "superior quality" benefit is an interesting one. I consider myself to be a good engineer who on occasion writes something beautiful. I like to share what's beautiful with everyone. This is something that's going to happen whether or not I pair (evidenced by my blogging). I know Mike does the same. I expect we're all proud of our most elegant solutions. However, more often than not I write fairly good software that isn't excitement provoking, but solves the problem at hand. I'm not sure anyone is benefiting from working with me at those moments. And, while it's possible that we'd get a slightly better solution if Mike & I paired, spending twice as many man hours for a 10% better solution doesn't seem like a great choice in the short term. In the long term those 10%s could add up, but what if I see the superior solution on my 2nd pass through and end up there while expanding a feature anyway? If I have a massive solution that might be a big cost. However, with small, focused processes I can tend to make a massive change to a process in ~4 hours. Delete is still my favorite refactoring and I do it as often as possible on my quests for superior solutions. Therefore, I don't believe those 10%s add up, I believe the 90% superior solution is often good enough or deleted.

I believe a few additional factors allow us to write code that is "good enough" on our own.
  • The application is fairly mature and many of the core design decisions have already been made.
  • Mike and I have Compatible Opinions on Software.
  • Mike and I are at a similar skill level.
In my current situation I find that many of the tough decisions have already been made and I can follow the existing path. And, any decisions that I do need to make I usually end up choosing what Mike would choose and solving in a way that we both think is appropriate.

While I believe "expansion of knowledge" is often undervalued and under-practiced in our profession, I don't think pair-programming is the most effective way to expand your skills. Blogs, books, and presentations allow you to work at your own pace and dig in to your desired level. My experience pairing with people using tools or languages I don't know have been painful. I did learn things, but I couldn't help but feel like there were much more effective ways for me to get up to speed.

The final 2 benefits that I need to consider are "collaboration" and "team support". As I previously stated, Mike and I collaborate quite closely. We're always both happy to stop what we're doing to provide an opinion or direction. I honestly can't imagine a more collaborative environment. Basically the same thing can be said of "team support" - we constantly watch each-other's back. We're both looking to succeed and we know we need each-other to get to that goal, so it only makes sense that we look out for each other. We don't need pairing to force us to support each-other, the desire to succeed is more than enough.

When considering my context and the "benefits" of (or, in my situation, lack of benefits of) pair-programming, I'm no longer surprised that I basically never want to pair these days. Also, looking back at the other teams I was previously judging - their context back then looks a lot like my current context. With a bit more experience under my belt I have to say I'm honestly a bit embarrassed for never even considering that they already "got it" and were already making the right choice. Oh well, live and learn.

While it's easy for me to examine my situation and make a determination I think there is a more general context where these same ideas apply. The aspects of an environment where pairing may not be beneficial seem to look something like this:
  • small team (< 4 people)
  • small software (components/processes can be rewritten in < 2 days)
  • motivated teammates
  • talented and well-seasoned teammates (similar skill level, and skilled overall)
  • the design of the application is fairly mature and stable
  • all team members have compatible options on software
Thanks to Michael Feathers, Alexey Verkhovsky, Pat Kua, Jeremy Lightsmith, Lance Walton, Dan Worthington-Bodart, James Richardson, and John Hume for providing feedback on the initial draft of this entry.

30 comments:

  1. Glad you wrote this up Jay. There're many practices these days that have swung far over the line into cargo-culting IMHO (pairing and TDD to name 2), and its refreshing to see an honest review of your situation.

    Nothing in life is absolute, and to treat it as such is foolish and closemind. Cheers to you.

    ReplyDelete
  2. I would interpret this article quite differently if I knew that you hadn't paired extensively in the past, and there lies the difference with blowhards who insist pair programming is (in general) a waste of time.

    @Jack, to be fair, one person's cargo-cult is another person's highly effective habits. As long as those at odds listen to each other, they will find a useful, balanced position.

    ReplyDelete
  3. (from one ex TWer to another) join the Dark Side, Jedi! The water is warm here (I kid! I kid!)

    This is seriously good writing Jay! your blog gets more interesting as time passes - a difficult feat to pull off.

    ReplyDelete
  4. Thanks JB & Ravi!

    Cheers, Jay

    ReplyDelete
  5. Over the years I've described pairing to other devs this way: you probably already "pair" 5-10% of the time with your coworkers - you occasionally sit with someone else and solve a problem. "Pairing" is like that except you do it most of the time.

    Lately I've been wondering if all that time the balance was much more "correct" pre-XP.

    I agree with everything in this article, including where pairing is still valuable. It's all very well said.

    (a former Pivot / current Squivot)

    ReplyDelete
  6. @JB Totally. A practice in and of itself is just that--it's when we all get in the way and throw absolutes around that things get messy IMHO.

    I don't come across many methodologies or concepts that have no value, all the time. They're just not valuable enough to be spread. I do come across some excellent ideas and techniques that get somehow turned into a panacea. Listening, as you said, and trying things out on your own, are key...and really not that hard to do after all.

    ReplyDelete
  7. @Jack That said, I don't remember the last programmer I met who couldn't benefit a lot from practising TDD. I have met programmers who simply can't pair -- as in, it's bad for their health to pair -- although I can count them on one hand.

    ReplyDelete
  8. Jay,

    "Delete is still my favorite refactoring and I do it as often as possible on my quests for superior solutions." This was my favorite part. Great quote.

    The "motivated teammates" aspect threw me. In your experience, have you found that pairing works well with unmotivated teammates?

    The "talented and well-seasoned teammates (similar skill level, and skilled overall)" aspect is important, and in my experience, that's a rare team. But maybe that's because I enjoy working with apprentices. :)

    ReplyDelete
  9. I tend to think that people who say that you should do something 100% of the time are always wrong. I'm a huge TDD fan but I don't do it 100% of the time and I don't have 100% test coverage. It always depends on the situation.

    There are pendulum swings in software development, and the pendulum is swinging from the get-it-done-fast-no-testing mantra to an emphasis on quality, which is good, but it makes me wonder if now we emphasize quality too much and speed not enough (I know that sounds heretical, but think about it). Like you said, is it worth it to spend 2x the time for an extra 10% benefit?

    But that being said, pair programming is definitely good, but I think you have to do the right thing in each situation.

    ReplyDelete
  10. @Dave "The 'motivated teammates' aspect threw me. In your experience, have you found that pairing works well with unmotivated teammates?"

    Unmotivated teammates can't hide when pairing is occurring. They either join in and get work done, or it becomes obvious that they need to be replaced - in my experience.

    "The 'talented and well-seasoned teammates (similar skill level, and skilled overall)' aspect is important, and in my experience, that's a rare team."

    It doesn't feel rare to me, as I feel like I could get that at forward.co.uk, thinkrelevance.com, or drw.com - but in the grand scheme of things I guess those places are 'rare'. I optimize for working on those types of teams as solving domain problems are the ones that are the most attractive to me - but that's just my approach, not a prescription for others.

    ReplyDelete
  11. I feel tempted to conclude from articles like these that pair programming acts like finger exercises for piano and organ players. Some lunatic fringe continue to enjoy the exercises, but most people simply play them in order to build up their general dexterity and evenness. Then we move on to studies, we play then regularly, but we rarely, if ever, perform them, unless they come from Czerny or Chopin, because those ones sound like music.

    I hated finger exercises, but I do prefer pairing. Perhaps I just like collaboration, and pair programming represents the most common way I get to do that. I imagine that if I worked on another Java project -- a platform I once knew very well -- that after I paired long enough to get up to speed on the latest and greatest tricks and tools, and assuming that I worked exclusively with people at a similar level of knowledge and experience... I might not insist on pairing so much. I might instead insist on pairing with business people.

    I hadn't thought about that before, so thanks, Jay, for prompting me to think about it.

    ReplyDelete
  12. Anonymous9:57 AM

    I just wanted to say that pair programming is WTF???? Guess you buy people for pair programming to pay each half of the salary. Why oh why would I want someone to be around my neck whole day? Highly unproductive!!!!

    ReplyDelete
  13. Anonymous10:23 AM

    It’s a waste of time unless you are mentoring someone else(an entry level guy)… or perhaps to fulfill the lack of interpersonal relationships :)

    excellent article

    ReplyDelete
  14. This depends on the programmers for the most part. If they are compatible to be a team, they can probably get good results.

    ReplyDelete
  15. Justin11:12 AM

    A balanced viewpoint is important. There is not only one way to do things. My team is also very small (3 developers counting my manager). I find that we switch back and forth between pair programming and not since we have a young developer on the team. However, I can't stand those who are so dogmatic and can't be flexible. It's another way of being "Agile".

    ReplyDelete
  16. Jay, you've written an excellent, thought provoking article on the whole. I am a little concerned that in pursuit of your point, you're pulling out numbers like "twice as many man-hours for a 10% better solution," without providing your basis for those specifics. In my experience of pairing and of not pairing, I have never been able to arrive at numbers which are that precise or cut-and-dried.

    On the whole, however, I do think you have an intriguing thesis; that pairing is less important where the work domain and codebase are more stable, and where the programmers have parity in competence. This means, presumably, that *turbulence in communication with the stakeholders is minimal, and *turbulence in communication between team members (due partly to variance in skill levels) is also minimal. This factor is further emphasized by the notion of a small team (which you mentioned).

    * by "turbulence" I do not mean conflict, but merely mis-matched expectations or conceptualizations.

    I prefer pair programming because I prefer work where turbulence has not yet been normalized: newer initiatives where neither the business folks nor the programmers already know most of what they need to know in order to accomplish what they need to accomplish. For me to avoid pair programming in a context like that would amount to living in denial, the metaphorical equivalent to searching under the lamp post because the light is better there. Pair programming is hard work precisely because it is built for doing hard things.

    The maintenance of stable systems exerts less demand in terms of communication/collaboration and also in terms of ideation in a new domain. But when an organization needs (or desires) to pivot in some way, we can't take for granted that lightweight, ad-hoc collaboration will get the job done.

    (For the record, I'm not saying that a maintenance cycle in the life of an organization is a bad thing. I believe organizations, just like people, need rest cycles. Pivoting may be dynamic and even dramatic, but perpetual pivoting is madness.)

    ReplyDelete
  17. Nice blurb.

    It reminds me of many situations where CTO's insist on patterns.
    "What pattern are you going to follow in implementing this widget ?"

    Reply: "It's a frickin widget !!! All widgets use the anti-pattern. (unless of coarse afterwards you find a pattern in it ;-))"

    As with all things, they must be taken in context.

    ReplyDelete
  18. Anonymous5:56 PM

    A good post. Programmers have always worked together when useful. But pairing is only useful where a high degree of knowledge transfer occurs, or at the point in the skill/difficulty graph where a second brain helps catch and correct serious design flaws (e.g. a trainee can learn from a senior, or two seniors can thrash out a critical design). However, when you have mature/capable programmers working on typical day to day designs (the simpler stuff rather than major architectural decisions) there is often very little to gain from expending two programmers on the task - if they can both provide an adequate (or better) solution, it is often pointless or downright wasteful to pair them. My view is always to use the right tool for the job, and pairing is yet another tool that should be applied in moderation.

    ReplyDelete
  19. Anonymous8:30 PM

    What if there is nobody to pair with :-(

    ReplyDelete
  20. When Sergey Brin wrote "google", who was pairing with him? How is "google" quality?

    ReplyDelete
  21. Worderful point of view, just figured you wrote my feelings :)

    Congrats.

    ReplyDelete
  22. Anonymous1:33 AM

    My pair was a reasonably good looking woman. I ended up having sex with her and I had to do large chunk of her work too

    ReplyDelete
  23. It's good to apply agile methods in an agile way, as opposed to the near religious fanaticism that many apply them.

    ReplyDelete
  24. Interesting. I agree that there are certainly places where pairing may not provide a balanced benefit and a small two person team is SOMETIMES one of those places. At the same time, as I engage with more areas of business, I find pairing more and more helpful in some of those two person relationships... such as pairing with different managers, BA's, PM's. Pairing in this context is not just a error check - it is a way to infuse different views/experiences into the creative process. It can also be a way that a manager can gain insight into the day-to-day realities of those he manages. Also, all pairing is not equal... I love this video showing the differences between just sitting together and "pairing" - http://agile.dzone.com/videos/pair-programming-show?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+zones%2Fagile+(Agile+Zone)

    ReplyDelete
  25. I should add an addendum: recognizing that there are better ways to 'pair' than others does not invalidate Jay's point - there are still places where pairing is not the best use of time... but more often than not, I find people use posts like Jay's to just avoid collaboration all together... basically, it sounds like Jay and his boss are getting all the benefits of pairing through their other communications - more like they are in a constant state of pairing - because they are in synch. It does make me wonder, however, what would happen if they added additional perspectives to their team through a third or fourth member.

    ReplyDelete
  26. Well done! I find your analysis persuasive with respect to the alleged pairing benefits you identified.

    But I think pair programming has one more benefit that you (and the referenced article) neglected to mention: a pair can catch and reduce the ever-present danger of WTF development.

    "WTF" is my most frequent reaction to the code I read ... whether written by me or others. My code is glorious when I write it; a few days later, however, and I'm wondering who wrote this crap.

    Does that sound familiar? I'll just speak for myself. When programming alone, all too often I pursue hair-brained ideas, corner cases, and features that I'm sure I'm going to need some day.

    I've spent hours polishing a piece of code that does things it shouldn't in ways it shouldn't with an API that no one will understand.

    Another voice might have caught my wandering muse and pulled me back on better course ... if only by obliging me to explain what-the-heck I am doing.

    I've never met the programmer who is immune to this disease.

    Of course a pair can produce delusional code too; they are just less likely to do so.

    Does this benefit alone justify pairing? It might if anyone could demonstrate that the time/pain saved by avoiding lone-wolf stupidities compensated for the cost of two programmers working on the same code.

    I don't know if such a study exists or how you would even design such a study. My gut tells me that the benefit would be measurable but not sufficient to justify the cost ... at least not in most projects. I remain open to a rebuttal on this score.

    I should add that code reviews are supposed to catch WTF moments without the double headcount cost of pairing. I don't know; in all my years I've never seen or been in an environment with adequate code reviews.

    In sum, I'm pretty sure I agree with you that pairing usually doesn't pay ... but it has more to offer than you grant it ... at least in reining in WTF.

    Cheers!

    ReplyDelete
  27. Anonymous11:28 AM

    Interesting article. I've paired in a few situations when it was very beneficial to me, to my partner and to our employer: 1) When I was a "trainee" 2) When I worked alongside the primary developer of a new, complex, shared code library 3) When working on a new app using tech that was new to both of us. But pair programming is not right for everyone nor for every situation. Sometimes a simple code review is all it takes to transfer knowledge, especially with mature apps and developers who are already fluent in them.

    ReplyDelete
  28. I'm surprised that you don't pair any longer. Your pitch to management about how you equate the benefits of pairing to being 2X the manpower for the same bang sounds like you're not mindful of all the benefits of pair programing. But I'm not going to try to convert you. You've already made up your mind.

    It's interesting to hear about someone who has expressed that they don't pair program any longer.

    ReplyDelete
  29. Really good honest post. For me, crucial is not forcing any such practise on anyone (I know organisations where this does happen). I'm also firmly of the opinion that it's not just coders should consider pairing:

    http://bit.ly/beyond-pairing

    I also consider that breaking routines by pairing great has potential to stimulate curiosity - it's all too easy to get stuck in ruts.

    ReplyDelete

Note: Only a member of this blog may post a comment.