JOHANNESBURG - Just what is pair programming? Extreme Programming defined it as two developers who team together and work on one computer to develop user stories. Does that work? That was my question last year, and I decided the only way to truly understand, was to pair programme myself.
I don't code much these days - like so many techies who've moved up the management ladder and away from programming, I regret having neither the time to spend at the code face nor the up-to-date development skills.
Although pair programming has been around for decades, uptake has been slow in many companies. I’d paired in a few workshops, but never for extended periods or on production code.
With a mixture of trepidation and excitement, I cleared most of my diary for three weeks. My pairing partner would be a senior developer who also lacked pairing experience, but came with all the language and environment skills necessary to supplement my rusty code abilities.
Our process was to write down a short list of tasks (using pen and paper) before starting. We religiously swopped mouse and keyboard every 10 to 15 minutes, if not sooner.
If you're new to pairing, the idea is that one person drives (for example controls the mouse and keyboard and does the typing) and the other performs a navigator role. The navigator directs the design and helps to spot coding errors.
It quickly became clear that errors are very easy to spot while you are navigating and not typing, but that you need to hold your tongue for the typing partner to complete at least that line of code. Interjecting too often breaks the driver's concentration. We established the courtesy of only pointing out typos once the driver moved on to the next line and had clearly missed the error.
We also made lots of short written notes.
This covered ideas for re-factoring, memory jogs for all sorts of issues we wanted to return to, and topics for further investigation. This helped us to maintain our flow on the section of code we were working on, rather than trying to keep too many threads in our heads.
A few hours into our first morning, and many keyboard swops later, we were flying through the code, but we both agreed that we were mentally exhausted.
Lesson one was that productivity was increased by pairing, way more than I had expected. This remained true throughout the 3-week experiment, although we did have some low days when we were sluggish and struggled with pairing. Overall, we had more days that were exhilarating and exhausting and satisfying. Deeply satisfying.
Lesson two, therefore, was that code quality was better under pairing by a significant margin. The fact that we were both experienced developers helped, and I'd assume that this benefit would scale with the experience of the pair. A junior pair would be good at reducing unintended errors like typos, but maybe not as good at predicting scenarios for errors. That still needs experience.
So far, we hadn't had any emotional outbursts or frustrations. Despite our early fears, our egos, experience and drive were meshing to produce better and better results. We took care to use respectful language when debating ideas, and to keep our hands off the keyboard when we weren't driving.
It’s ridiculous how hard it is not to want to type when your partner is the driver and is being a little slow with a concept. Of course, “being slow” is relative. It’s much easier to see what to do as the navigator and with the luxury of taking a metaphorical step back. Understanding that your partner will also see you as slow when you're the typing driver is an important step to being humble.
Lesson three was “how not to be an asshole”. Give your pairing partner the space to solve problems too. Don’t dominate the process, and never grab the mouse or keyboard out of their hands.
Another joyous experience was the cleanness of our solution. We had great debates around code design. This went far beyond the kind of design sessions I’ve done in the past in Sprint Planning (SP2) or similar design sessions.
This was micro design, method by method, test by test. Did we really need that public variable, how could we better encapsulate that concept, was this piece of code not similar to the piece we wrote yesterday? We shared knowledge, experience and thinking to produce code that we didn't hate at the end of the project. Big win!
That was lesson four: pairing produced a clean, maintainable working solution that was closer to textbook perfect than most code that makes it into production. Clean code is a good thing, and I'll write a different post to explain that some other day.
Lesson five was all about learning. I refreshed my rusty code skills, but the learning was by no means one-directional. I could contribute design ideas and code approaches from the get-go, because I came to the pairing with a unique set of experiences.
Once I realised that I had something to contribute, my confidence grew. That accelerated my learning as it was such a positive experience.
In our second phase we worked on technical debt and refactoring for a large C# project, and my learning swung from code to domain issues. A common experience when learning a new system is trying to get help without being a nuisance to other team members. It’s a really negative experience. By contrast, pairing with someone who knew the domain turned a potentially big negative into a non-issue.
I’ve moved from intellectually believing that pairing was a good idea, to a deep connection with the behaviour it encourages and the outcomes that it produces.
My conviction now is that teams should be encouraged to pair all the time.
There are environmental challenges - some desks are too small to allow two developers to comfortably share the space. Armrests on chairs are also a nuisance, and we found ourselves playing chair “bumper cars” a little too often. The ideal office space will need to take seating needs into account for pairing to work long-term.
Personalities play a big role - the solo genius is not a useful team member when you want the team to pair. Maybe they never were useful on a team. Software is a creative activity requiring high interpersonal communication skills, and the teams that are successful communicators will do very well when they adopt pairing.
I’ve found three big obstacles to pairing. The first is ego, where a developer either doesn't want to share their knowledge or believes that they are too good to need to work with someone else. Not sharing knowledge is a big problem for any team and leads to silos. Address that as soon as you can, because it puts your project at risk.
Believing they are too good to pair is best tackled by pairing them with someone they can learn from. If you don't have any other strong developers in your team, that might be a red flag. Why not? Is the strong developer taking all the complex tasks and denying the rest of the team the chance to learn? Whatever you find, like a lot of Agile practices, it's good to identify your issues and start to tackle them.
The second issue is imposter syndrome. This is where a developer has low self-esteem, and fears being discovered to be a fraud, or simply not very good. It’s a syndrome and mostly not true. Pairing will help them to calibrate where their skills really fit, rather than living with the fear of not being good enough.
The final issue I encounter far too regularly comes from management. This is the belief that pairing will cause every task to cost double, because two people are doing the work that was previously done by one.
There are some great statistics on the cost of finding and fixing issues in code late in the production cycle. It’s very sobering how much of the cost of software occurs after the initial code is written. I’d suggest approaching management with industry stats as well as tracking your team’s defect rate after you’ve started pairing. Metrics are always easier to defend than opinions.
Feedback is the cornerstone of improving. I’m giving pair programming a resounding thumbs up. I hope you do too.
Steyn is co-Founder of Khanyisa Real Systems.
The views expressed here are not necessarily those of Independent Media.
- BUSINESS REPORT