- Consulting / Coaching
- Jeff’s Blog
Passive review after code (PRAC) is largely a waste of time.
In this blog post for Ranorex, I provide some reasons why active review is better than PRAC. I discuss pairing and mobbings as two forms of active rule, and present a core rule for review that focuses on outcome instead of mechanism.
Balancing Mobbing, Pairing, and Solo Work (21-Jun-2018)
(Well, I like the Oxford comma, even though my editors do not.)
I view modes of working as akin to tools–you want to use the right tool for the right job or situation. In this blog post for Gurock, I talk about the distinctions around appropriateness for mob programming and pair programming. I also admit to enjoying the ability to work alone from time to time.
“Pairing is hell. Okay, it’s also fun. But it’s also hell.” —Alex Harms, on pair programming.
Over fifteen years of pairing, and I too am similarly ambivalent about it. Don’t think I’m making a case for not pairing, however. I’ve written numerous times in support of pairing:
At least 16 more blog entries on this site discuss pairing, as do many at the Agile in a Flash blog.
So “hell,” really? Seems strong. Let me explain what I find to be a few serious problems with pairing cultures that can make it hell.
As an introvert, I have a limit on the number of hours I can interact with people before I need to recharge (i.e. on my own). I regularly stretch this amount, which is ok. It doesn’t mean I’m not enjoying the interaction–particularly if it’s going well. It is heavily draining, however, which demands more recharging.
Pair programming was never meant to be the only thing you do all day. And yet I’ve done regular stints of 9-10 hour pairing days (at HEB in San Antonio for 7 months), or 7-8 hour days (remote at Outpace for the past few years). Trust me, those aren’t 100% fun hours for an introvert, no matter how well it’s going.
Sensible pairing shops set a limit on pairing. Six hours is plenty: three hours in the morning, three in the afternoon, a break in each. One shop I’ve helped mandates such a schedule to positive effect–no one feels pressured to stretch beyond reasonable amounts.
Some people either never learned to play well with others or are incapable of it (i.e. it’s not their fault). Still, I believe most individuals are capable of learning how to interact effectively as a pair.
Having said that… there are definitely a (very small) number of pair-holes: people who should just not pair. Ever. Again. And I hope to never have to pair with these folks again. Fortunately for them and me, plenty of shops don’t mandate pairing, and shops that pair usually have other non-pairing things to do.
What makes a pair-hole? Mostly it’s someone who’s “always right,” or worse, someone who wants to argue (and not code) just for the sake of arguing. A keyboard dominator can sometimes be a pair-hole.
Many bad pair habits (inattentiveness, timidness, loud, etc.) can be corrected or overcome. A pair-hole is someone who doesn’t care enough to do so.
I’m not talking about people who want to think through problems on their own instead of with a pair. I think just about everyone feels that way some of the time, including me. I find that exploring things on my own is necessary as a regular thing. I find time regularly to do so–that’s one reason I seek slightly less than a full day’s pairing.
Other than pairing too long, I’m mostly talking about pair marriages. We promote pair switching to increase coverage on everything. A pair can go down a rathole, just like a solo dev can. I suggest all shops incorporate a rule that says “at least 3 sets of eyes review every story,” whether through pairing or some other mechanism.
That’s the practical concern regarding pair marriage. The painful part: Being stuck with the same person day after day–or even all day long–can be a big pairing turn-off, like long walks down the beach can be (because you know you have to walk back). Switching at lunchtime can work well.
Pairing can be a highly entertaining, effective tool. For me, it’s often joyful. But it can at times be painful. The more you understand the extreme feelings and concerns people have with respect to pairing, the more you’ll learn how and when to effectively employ the tool.
If you’re not actively coaching your pairing and not continually adjusting your pairing practice (perhaps as a result of retrospectives), chances are good that you have the above dysfunctions.
In “TDD Is Not a Silver Bullet” I reproduced part of an interview with Tim, a sharp young corporate developer that I’d paired with very briefly in 2006. In 2008, he sent me an email about his experiences in the interim. Tim’s stories are what prompted me to want an interview with him. Here’s a portion of the email.
Much to my surprise, it is being conveyed from the head of our development that we need to be “stressing” TDD. My surprise was… I thought we already were practicing TDD on an enterprise level. Regardless, I guess they had brought in this guy named [Very Big Agile Name deleted]. (I am sure he runs in your circles.) If you are friends with him, take what I am about to say not as an insult, rather my perception; but if he would have been the expert to introduce me to TDD, I would never even thought of adopting/agreeing with it. And, as it turns out, the teams he consulted felt the same way.
I have been telling my boss about my experiences with you, and told her it would be like night and day. I respected the fact, that while TDD was the stressed point with you, you also provided more than just using TDD as a silver bullet per se. Basic things… like knowing the language, having fun, communicating, and so on.
I got in touch with Tim this week to make sure he was ok with me publishing this stuff four years later. No surprise, Tim is still doing (and presumably enjoying) TDD.
If you’re a “real” programmer, you find coding fun at least some of the time. Of course, it might not necessarily be fun when the code fights you all the way, hiding bugs and throwing nasty dependencies in your path. Still, I happen to enjoy coding always, despite the challenges. Test-driving is fun, too–it’s more code, and it gives me confidence to craft cleaner code, which is even more fun.
Maybe learning doesn’t have to be fun to be effective, but I have to figure sucking the fun out of it on purpose can’t possibly work. (I’m disappointed that a Very Big Agile Guru could do that.) Yes, the sticky challenges of real code mean that you can’t teach TDD with a few trivial, “non-real-world” examples. That’s why I employ a deliberately horked-up, fairly realistic codebase in my training. But the class also learns that it’s only a challenge, not a barrier, and they quickly learn a few simple techniques to surmount the challenge. They have a good time learning TDD.
Ultimately, my students leave the classroom enthusiastic about the prospects for TDD, and confident that they at least have the basic understanding needed to begin tackling their challenges. After that, it’s a matter of their having good support for the practice. (Being the minority in a team, as I’ll relate in a later blog post through Tim’s stories, is a great way to lose that enthusiasm.) When I get to pair with developers to help them through learning TDD, both of us have a good time.
If you’re interested in coming up to speed on TDD, make sure you pick trainers and consultants who don’t suck the fun out of it.
The first rule of Fouled-up-code* Club is you don’t talk about the code.
The second rule of …
We don’t talk about the code, and so most of us are members of F’d-up-code Club. We’re not socializing the code enough. Shop upon shop I visit, I ask when the programmers discuss what’s in the code with each other. The usual answer? “Once in a while.”
If you’re not regularly talking about the code as a team, it’s getting worse. And “it” includes the time to understand the code, the time to fix the code, the pain the code causes you, the defect count, and ultimately the extent to which you have a real team.
We create standards but they idle and adherence falls off, and the code shows it, and attempts to get back on track fall short. We pair-program, but don’t switch pairs mid-story, and the solutions show it. (Yes, two heads produce a better-than-one solution, but a pair deep into understanding of their feature can easily produce a solution that makes little sense to others.) We hold tepid brown-bags that bore attendees and ultimately taper off in quantity. We hold retrospectives, sometimes, but the process crud dominates, and the audience isn’t usually right for talking about code problems. We sit in the same area (well, a small number of us do), but rarely call others over to our monitor to look at some cool or challenging code.
Try this (the opposite of the prior paragraph, duh):
* More blunt folks can substitute other words for “fouled.”
When writing, be careful of presenting an opposing point first with the notion that you’ll make your counterpoint in a subsequent paragraph or page. That first pitch is often as far as some readers get. Royce’s article “Managing the Development of Large Software Systems” led to decades of waterfall for this reason.
Recently, a pair-developer expressed concern over the use of multiple returns in a short method. I said I knew about the long-standing rule but that it created little value for very short methods. Two days later, I heard the same concern during another pairing session. Twice in one week? Curious!
I asked where they’d read about the rule. “Uncle Bob’s Clean Code” was the surprising response. “Hand me your copy!” I insisted, a bit worried, and quickly located the text in the functions chapter. The very last paragraph on page 48, starting a new section, states: “Dijkstra rules of structured programming… [say] …every function … should have one entry and one exit. Following these rules means that there should only be one return statement in a function…” Oh! Yeah, I learned that 30 years ago. Really, Bob?
Page 49, top paragraph: “”While we are sympathetic to the goals and disciplines of structured programming, these rules serve little benefit when functions are very small. It is only in larger functions that such rules provide significant benefits.”
Oh, ok. Whew! Crisis of faith averted.
Readers: Inattentive reading can be embarrassing!
Writers: Don’t assume readers will get to your point. Make it first.
For almost a year, I pair programmed on a daily basis as part of a team working for GeoLearning, a small software company that is no more. My enjoyment was tempered by the fact that I was pairing remotely, online with a headset and sometimes a camera, using Skype and WebEx. The contrast to live pairing was marked.
Pairing or not, as a remote developer I didn’t feel like I was a real part of the larger, “live” team. I felt that my influence as a remote person was insufficient.
The remote pairing also carried the same issues that “live” pairing can create, most of which are minor. For example, the team had very few standards, which led to some wasteful debates during many of the pairing sessions, still not that big a deal. But couple a lack of standards with stubborn people, and you have a useless pairing session.
I can get along with just about everybody; not the case this time out. I paired with one developer whose concept of TDD was almost completely opposite mine. We produced virtually no useful product during our two or three pairing sessions (we then ended up on different teams, thankfully). In attempts to stop the arguments, I would often say, “Let’s just go with your preferred way of doing things for now.” No such luck. Some folks are simply contrarians.
Remote Pairing Pros
Being remote sucks in so many ways–primarily the isolation from the rest of the team–that I wouldn’t have even considered the position had it not been for the ability to pair. I never felt like I was a real part of the larger, “live” team, and I felt that as a remote person I was unable to influence the team much.
So despite the negative aspects of my remote pairing experience, it was the best that I could expect for this opportunity. Ultimately, having this opportunity remotely was better than not having it. And the pairing brought me a small but significant step toward feeling like I was a real part of something.
I’m currently working a three-month contract for a local firm. It’s a very stable company, there’s no travel on the near horizon, and my commute is about seven minutes door-to-door (it’s three miles away, with only one stoplight inbetween). Those three elements are great, but just about every other element–ranging from pay to preferred way of working to technology–is a concession.
There’s no pairing. My first “real” week (i.e. past most of the HR and setup BS) was spent sitting in an office, digging through a (test-less) codebase, occasionally IMing my teammate a couple offices over to ask questions. It’s a typical no-process environment.
Here’s how I feel about no longer pairing:
Pairing is not for everyone or every team. The bullets above suggest that there are serious challenges both with pairing and with not pairing. But most of the time, I’ve found pairing to be far more enjoyable and productive than not.
When pairing, I often learn little shortcuts and tips that I might never pick up otherwise (even though I’m the compulsive sort who comprehensively reads things like the entire list of commands, just to find some new trick). I try to impart at least as many tips as I take on. Pairing makes it happen, as there’s little better than to have an insistent partner who keeps reminding you to “just hit Ctrl-Alt-v” (introduce variable in IDEA, an essential refactoring). In the absence of a pair, IDEA’s Key Promoter plugin helps a bit.
As someone who pairs across many teams, I regularly encounter different IDEs and programmer editors. Usually teams standardize on one tool, but not long ago I worked in a C++ team where there were 8, count ’em, 8 different editors in play. Currently I am working with a team where some people are piloting Eclipse, while the rest of the team uses IDEA.
Give me a few minutes and I can ramp up OK, but switching IDEs throughout the day will make just about anyone feel stupid. Ctrl-d, duplicate line in IDEA. Switch to Eclipse, oops, Ctrl-d, I just deleted a line. Nope, it’s Alt-Ctrl-Down to duplicate a line. Move a line up, Ctrl-Shift-Up in IDEA. Wait, though, I can’t remember the Eclipse corollary, but I do have muscle memory, and so I now have to go try it… wait for me… it’s Alt-Up. And so on.
Why don’t I just change the keymaps so that they’re more in synch with each other? Or why not use, say, a vi keymap everywhere? The problem is that I’m pairing with others, and so the simplest thing is to go along with the IDE defaults (which is what the predominance of programmers uses).
On my wish list and/or backlog of things to work on, I’d love it if IDEs would support a standardized roaming keymap protocol, as well as a simple mechanism for toggling profiles. I would be able to specify a URL from which the IDE would download my profile. From there on, a simple keystroke would toggle from the active keymap profile to mine and vice versa, in order to expedite pairing.
I’ve been hoping to see more support in IDEs for things like TDD and pairing. It’s coming, albeit slowly. Any plugin fanatics out there who want to give this one a go?
Tim Ottinger and I are working on a new project, an agile agile reference guide. (Yes, that’s supposed to be two “agile”s in a row.) One of the things we’re debating is a list of pairing smells. Here’s what we have so far:
Thoughts welcome, and incorporated ideas will be rightly attributed. What might we remove from or add to this list? What could be worded better?
Rather than whine about not having enough good pairing experiences, I’ve decided to do something about it. Recently I’ve had a few pairing sessions online, and I decided that the software to build would start around the simple notion of scheduling online pairing sessions.
The idea is to slowly start building an online pairing community. I imagine there are many kinds of participants, people who want to:
I hope that the scheduler software will be all that and many more. Initially, I created a wiki as a scratch pad area, to help set up sessions, to hold an initial backlog of stories around the scheduler itself, and to record experiences.
I chose Java, but only because of interests in my pairing partner. I’m not sure that the pairing scheduler should be Java, but for now it is. If Java, what represents the best choice for front end (web) technologies?
Please feel welcome to join up and post your recommendations and experiences at the wiki site. Interested developers should send me an email with their intents, and I’ll set up their SourceForge account to have appropriate access.