Archive for the ‘Pair Programming’ tag
I’ve written a lot of blog posts in the past about pair programming and the advantages that I’ve seen from using this technique but lately I find myself increasingly frustrated at the need to pair 100% of the time which happens on most teams I work on.
From my experience it’s certainly useful as a coaching tool, as I’ve mentioned before I think it’s a very useful for increasing the amount of collaboration between team members and an excellent way for ensuring that knowledge of the code base is spread across the team.
On the other hand I no longer see it as the silver bullet which I did previously and I think we do lose some useful things if people get forced to pair all the time.
Time to explore the code
Mark Wilden wrote a blog post about 18 months ago where he pointed out the following:
Pair programming doesn’t encourage quiet reflection and exploration. You can’t just sit back and read some code. You can’t just sit and think. I mean, you can, but then your pair is just sitting there.
On the project I’m working on at the moment we pair on everything so if you want to spend some time scanning through the code and seeing if there’s ways to improve it then you tend to end up doing that in your own time.
If I start to explore the code or do some scratch refactoring, while pairing, to see how the code would look if we structure it slightly differently then unless my pair is interested in what I’m doing then more often than not they’ll start playing with their phone.
The alternative is to try and explain exactly what you’re trying to do but more often than not you’re not entirely sure or it takes longer to explain than to try it out.
I think we can easily create this time for people in the day by just agreeing to pair maybe for 7 1/2 hours in a day instead of 8 hours.
In the name of (short term) productivity
When you’re working as a pair one of the things that it’s supposed to improve is the productivity of both people – it’s much easier to get distracted by something or go down a rabbit hole when you’re on your own than if you’re pairing.
On the other hand I’ve started to wonder whether what we’re actually achieving is short term productivity.
In my experience house cleaning tasks such as investigating why a test is ‘randomly’ failing on the CI machine are less likely to be looked at if everyone on the team is pairing 100% of the time because it interferes with productivity of a story.
There is some logic to that because investigating things like that can lead you down a rabbit hole but not addressing them isn’t particularly helpful either since they’re bound to ‘randomly’ fail again in the future and cause pain.
I think pairing can also be detrimental to learning how to use new tools although I can certainly understand the argument that you should be learning things like that in your own time anyway.
For example I know a little bit of Sed and Awk and there are often times when we need to do text replacement across a series of files and it’s very boring for my pair to watch while I try and work out exactly how to do that.
More often than not we end up doing that task manually which is slower but less frustrating for the other person.
I think pairing works very well when there’s a new problem to solve and there’s some thinking to be done around how to design code but it tends to diminish once we’ve built the cookie cutter.
A reasonable amount of the work required to develop a standard web application is quite mundane once you’ve worked out how to do it any subsequent work in that area tends to be about following the established pattern.
It might not be the best pattern but in my experience it’s less likely that you’ll go against the pattern if you’re pairing since you’ll have your ‘productivity’ hat on.
There is an argument that if you’re pairing and it’s boring then you should find a way to automate that problem or make it possible to write less code.
There have been times when I’ve seen pairs do this but I’d say in a lot of cases there isn’t a significantly better way to solve the problem.
Jay Fields recently written a post about his experiences after pair programming and while I don’t think the types of projects I’ve worked on are ready for his approach I don’t think 100% pairing is the answer either.
Another interesting pair programming ‘technique’ which I rediscovered while pairing with Priyank is that of doodling or drawing various parts of the solution when your pair is writing code.
I find that this helps to stop my brain wondering off and lets me reflect on what we’re doing from a higher level.
As an added bonus it also seems to allow me to listen more effectively to my pair.
From what I’ve noticed it works most effectively when the other person is reasonably comfortable with the code base and language which was certainly the case when I was pairing with Priyank.
I guess they also have to be reasonably comfortable with the idea that you’re still listening even though you’re not necessarily looking at everything that they type.
It doesn’t work quite as well in other situations where you’re playing more of a coaching role because you need to be more focused on the code that’s being written and provide help with respect to syntax, libraries or context on the code base.
I don’t remember noticing many other people doing this so though maybe this is just a solution for my ADHD.
I’ve noticed recently that while pairing with various different people that I frequently ask my pair what they’re trying to learn through the approach that they’re about to take.
I tend to use it when I don’t really understand what my pair is doing and want to find out so that I can stay engaged.
It seems to be a more effective and less confrontational way of finding out than saying “What are you doing?” or “I don’t understand what you’re doing”.
There tend to be two outcomes from asking the question:
- We were about to go on a yak shaving mission and that’s not been averted.
- My pair was ahead of me, knew something that I didn’t and is now able to teach me that.
The following are some recent examples I can remember asking the question:
- My pair was googling how to do something which didn’t seem directly related to what we were doing.
- My pair was scrolling around files fairly rapidly and I wasn’t able to follow what they were doing
Of course this question is unnecessary if the driver is providing constant commentary about what they’re doing but it’s easy to forget that you have someone alongside you when you’re solving a problem.
Asking this question seems to be a reasonably effective way of keeping the pairing collaborative.
Having said that there are often features which require both front end and backend collaboration and we’ve been trying to drive these features from the front end through to the backend rather than working on the backend code separately and then working with Les later on to hook it all up to the frontend.
As a result we’ve found that it seems to be most effective to prototype any backend code that we write while working together such that we just write enough code to allow us to see that everything is hooked up correctly.
Once we’re happy that we’ve got that working correctly then we split up and work side by side, effectively parallel pairing as Vivek Vaid describes it.
At this stage I would focus on driving out the backend code properly with a more test driven approach and Les works on tidying things up from a front end perspective and ensuring that the feature’s look and feel is consistent across browsers and doing any other front end related functionality.
The benefit that we’ve seen from doing this is that we’re able to work together on the code where we get the most value from doing so and then split up to work on the other things where we wouldn’t add as much value to each other in a pair programming situation.
Since we’re working directly together at the beginning of a story we also get the benefit of iterating/talking through the potential approaches that we can take and I’ve often found that I take a better approach to solving a problem when working with a pair than when working alone.
The thing that we have to be careful about when doing this is ensuring that we’re not treading on each other’s toes because we are working around the same part of the code base and often on the same files.
This means that there is a bit of merging to do but as we’re also sitting next to each other it hasn’t proved to be too much of a problem. I think using a source control tool like Git or Mercurial with their merging capabilities would probably make this a non issue.
It seems to me that we’re still getting the benefits of pair programming with this approach and I’m more convinced that this might be a useful approach in other situations as well.
Mark Wilden pointed me to a post he’s written about his experience pair programming at Pivotal Labs where he makes some interesting although not uncommon observations.
When you pair program, you’re effectively joined at the hip with your pair. You can’t pair if only one of you is there.
I’ve previously written wondering what we should do if our pair isn’t around where I was leaning more towards the opinion that we should try to continue along the same path that we were on when working with our pair if they’re gone for a short amount of time and to find a new pair or work alone if they’re gone for longer.
On the projects I’ve worked on we’ll still have times working alone when there’s an odd number of people around or if someone just feels like working on their own and I think that’s fine as well. I don’t think we need to pair 100% of the time.
You have to be able to think out loud – 8 hours a day. Then you have to type in code while someone is watching you. They’ll catch your typos (hopefully after giving you a chance to spot them yourself) and they’ll see when you’re floundering for how to do something.
I find that this is quite a useful practice for explaining things to yourself although I can see how it would initially exhausting.
Even now there are times when I just want to write some code instead of having to explain what I want to do to someone else. Sadly almost every time I explain something it turns out that my pair has a better idea of how to do it than me so I’m always glad pairing encourages this conversation.
Pair programming doesn’t encourage quiet reflection and exploration. You can’t just sit back and read some code. You can’t just sit and think. I mean, you can, but then your pair is just sitting there.
This is a bit of a double edged sword – pair programming does encourage us to get things done but it’s also true that sometimes we need to get the whiteboard out.
Often just sketching out the problem on a piece of paper to check your understanding is enough to trigger a conversation which might result in a better solution.
It does tend to need one person to drive this process though. I haven’t seen it just happen organically.
We rarely pair 100% of the time so there are often times when you get a bit of time to play around a bit with the code and see whether specific approaches would work out and I often use this time for reflection and exploration.
One thing which a couple of the commenters on the original blog suggested is that perhaps more rotation was needed to help overcome some of the problems and from my experience it’s vital that we do rotate otherwise the pair will end up hating each other!
I recently worked on a story with 3 other people across its life and each person pointed out something that I hadn’t previously considered and which led to an eventual output that was much better than it would have been otherwise.
I think rotating different people onto a story can help lead to more innovative design as long as we have people working together who are relatively flexible and open to trying out new ideas.
Mark’s post is certainly interesting though and helps identify some of the things we need to be aware of when pair programming – we don’t just want to follow the practice blindly.
I came across a couple of quite interesting blog posts recently which described some approaches to interviewing which suggest a more empirical approach to interviewing whereby the interview is treated more like an audition for the person being interviewed.
I like this idea and it’s something that we do when recruiting developers in a pair programming interview.
The general idea is that we pair with the candidate as they go through a coding problem. It’s perhaps a little different from a normal pairing session in that the interviewee is more than likely driving for the majority of the session.
Sometimes we might also have another interviewer observing the pairing session and giving input where necessary.
While many people may not have specifically pair programmed before nearly everyone has worked with someone else at one computer on a problem so I haven’t ever found that a candidate finds it too much of a leap because they’re used to working alone.
One of the really cool things about a pair programming interview is that it’s much closer to what a real situation on a project would be like which I think helps you to gain a more accurate picture of the skill level and potential of the interviewee.
As an interviewer you get the chance to see how quickly the interviewee will pick up new ideas, to an extent how well they work with other people and first hand experience of their level of expertise when it comes to coding.
From my experience of other types of interviews it can be quite difficult to tell exactly how much knowledge someone has in a specific topic but in a pair programming you can just see for yourself so it works out quite well in that sense.
It’s certainly not fool proof and I quite like the way that Hash Rocket have taken this idea to the next level and get people to come there and pair program with them for a week before they get hired.
This seems like the next logical step and I guess if you have the ability to do this and candidates are prepared to give up their time then it’s a really useful approach.
As Knut Haugen points out, the interview process is as much an opportunity for the employee to work out if they actually want to work for the potential employer and I think having the opportunity to pair with some of the people who work there is a great chance to assess this.
Dave Nicolette suggests that the pairing part of the interview process is considered the only meaningful part of the interview process in the team he’s coaching and while I’m not I’d go that far I do think it’s a very valuable approach and one I’d recommend even if you don’t pair program all the time on your team.
The idea of getting people to help each other rather than pair program is what stood out for me this time, something which Brian Guthrie also pointed out:
“We didn’t do pairing, we did ‘helping’. You can’t get alpha progs to ‘pair’ but they’ll tell you what they know.”
It’s been quite common at the places that I’ve worked at for pair programming to be frowned upon and sometimes that’s not the most important battle to fight so the team will be more selective about its use.
I was discussing this with some colleagues this week and it does seem that pair programming is a trigger word/phrase with negative connotations for productivity.
On the other hand, something which is rarely frowned upon is having a team ‘working collaboratively’ and in fact most of the time this is considered a very good thing.
When we work alone I still find myself calling a colleague over to help me out when I get stuck and while I could probably work something out alone given enough time I don’t think that approach makes sense when working on it with someone else leads to us solving the problem much more quickly.
Josh Bloch speaks along similar lines in the interview with him in Coders at Work:
I don’t like working in total isolation. When I’m writing a program and I come to a tricky design decision, I just have to bounce it off someone else. At every place I’ve worked, I’ve had one or more colleagues I could bounce ideas off of. That’s critically important for me; I need that feedback.
I’ve known people who don’t feel this way – who are willing to program in a vacuum. I think it hurts them.
I think it’s fairly inevitable that if a team is to deliver software effectively then there are going to be times when people are working together to solve problems.
What we choose to call that can be varied depending on the context we find ourself in.
A colleague and I were working on some code a couple of weeks ago which mostly revolved around investigating the C# reflection API to work out which methods we needed to use.
My colleague was driving while we were doing this and our progress seemed very much based on intuition about the API rather than being gradual.
In fact it was quite similar to one of the situations in which Uncle Bob suggests TDD doesn’t work so well:
I need the freedom to fiddle around with the formatting and the structure until everything is just the way I want it. Trying to do that fiddling with TDD is futile. Once I have the page the way I like it, then I’ll write some tests that make sure the templates work as written.
My colleague was fiddling around with the code trying to work out what combination of methods we needed to call and I was struggling a bit to get involved through no fault of my colleague.
He was describing what he was doing but for a lot of the time what we tried didn’t work and then suddenly it worked.
It all seemed a bit magical to me!
At this stage we decided to refactor the code and thought that it would might be useful for me to do that refactoring so that I could explain my understanding of the code my colleague had just written and see if I had followed what he’d been doing.
I was able to extract out methods correctly most of the time but there were a couple of places where I hadn’t quite understood what was happening so this approach allowed my colleague to explain it to me.
My initial thinking when we started doing this coding was that perhaps it wasn’t suitable for pairing because it’s quite exploratory but it seemed to work out reasonably well and my understanding of reflection is now slightly better thanks to my colleague’s explanations.
In this weeks book club we discussed Arlo Belshee’s paper ‘Promiscuous Pairing and Beginner’s Mind‘ where he presents the idea of rotating pairs more frequently than we might usually, suggesting that the optimal rotation time is 90 minutes.
I remember coming across the idea of promiscuous pairing a couple of years ago but I hadn’t read the paper all the way through and so far haven’t worked on a team where we’ve really tried out his ideas.
These are some of my thoughts and our discussion of the paper:
- I found the section of the paper where he talks about skills and competencies quite interesting – the suggestion seems to be that for any given task the least skilled person for that task should be the one to do it but that the person should still have the necessary competency to execute it.
I’m not entirely sure of the distinction between skills and competencies – Belshee suggests:
The difference is simple. People can learn skills in a matter of months. People can’t learn competencies in less than several years. There aren’t many things that fall between — qualifications are almost always skills or competencies.
Software development wise this would suggest that a skill such as object orientation would be more likely to be a competency but what about a specific programming language?
It is possible to learn your way around a language to the point where you can do some productive things with it relatively quickly but for me at least there are still things I don’t know about in the languages I work with and I’ve used some of them for a few years now.
- There is a nice quote from the paper when discussing the idea of giving tasks to the least qualified person, that ‘the least qualified teams produced the code that had the fewest surprises‘ – I imagine this is probably down to the fact that the least qualified person probably doesn’t yet know how to do clever things with a language so they just do the most obvious implementation. I think this is certainly what we want to happen when a team is working on code together.
- I liked the discussion of beginner’s mind where he talks about it being a transitionary state that we move into when are in a situation that is unfamiliar but near the limits of our comfort zone and that we will move out of once we are comfortable with the current situation.
It seems like this state of mind links quite closely with the idea of deliberate practice that Geoff Colvin talks about in ‘Talent is Overrated‘ – the idea being that in order to improve most effectively we need to be doing activities which are just beyond our current competence.
- I’ve frequently noticed that people are reluctant to swap pairs until they have finished the story that they’re working on – Matt Dunn pointed out that this is probably linked to human’s natural desire to finish what they’ve started!
Belshee seems to get around this problem by ensuring that the tasks being worked on are sufficiently small in size that they can be completed within one or two pairing sessions.
A lot of the work that we do is integrating different systems where there is quite a bit of exploratory work to find out what we actually need to do first – it would be interesting to see if quicker rotations would be appropriate for this type of work or whether a lot of time would be spent bringing the new person on the pair up to speed with what’s going on.
- We had some discussion on pair programming in general – Raphael Speyer described the idea of ‘promiscuous keyboarding‘ as an approach to try within a single pair. The idea is that the keyboard switches between each person every minute which hopefully leads to both people being more engaged.
I find that quite often on teams people will roll in and out of pairs when there help is needed on something – Nic Snoek described this as being ‘guerilla pairing‘ and I think it is something that a technical lead of a team is most likely to engage in as they move around the room helping people out.
I often feel that pair programming is a skill that we take for granted and we assume that we can just put two people together and they’ll be able to work together effectively.
From what I’ve found this doesn’t always work out so I think it’s important to keep innovating and trying out different things in this area so that we can find approaches that allow us to work better together.
As Dave suggests it should be ‘guerilla’ and not ‘gorilla’ pairing that Nic suggested as being a useful idea.
I’ve been pairing a bit more regularly recently after more sporadic pairing sessions over the last 9 or 10 months and I’ve noticed that I’ve picked up some habits which aren’t really that effective when pairing so I’m on a mission to sort that out.
Moving around the code too quickly
One thing that I often forget is that when you’re driving you know exactly where you’re going with the mouse or keyboard just before you do it whereas the other person doesn’t know until you’ve done it.
As a result of this it is useful to commentate on what you’re about to do and not move around the code at break neck speed, but instead take your time and pause after each step to allow your pair to follow where you are in the code.
It seems like this might slow you down but I find that quite frequently when I race around the code in this way I’m making assumptions about the code and I didn’t even know that I was doing it.
Having someone else working alongside you forces those assumptions out into the open and it’s amazing how often you end up going a different way than you had originally assumed.
Moving through the code more slowly is especially important if you call someone over to help you with something since in this situation they have very little idea about what you’re doing so they won’t be able to provide much assistance unless you take the time to provide the context to them.
Not listening to other solutions
Another trap which is best to avoid is always thinking that you personally have the solution to all the problems the pair encounters and that your solution should always be the one used.
I think this becomes a particularly easy trap to fall into when you’ve learnt a few ways to solve problems and the temptation is to always use these solutions and block out suggestions which we judge as being inferior to our solution.
George Malamidis taught me something about code attachment a few years ago: You always gain by allowing someone to show you an alternative solution. If someone wants to solve a problem in a different way, there are several gains to be had. If their way is inferior, you have an opportunity to mentor a team-mate. If their way is equally elegant, you’ve gained another solution, or point of view that may be superior in the future. If their way is superior you learn something new and the codebase improves. In exchange for these gains you only need to give up time. Time is valuable, but it’s also well spent on improving the ability of a team-mate or your personal ability.
I noticed that when working with my colleague Lu Ning I wasn’t very keen to understand his ideas about how to structure code and move data between the client and server sides because I was convinced that the way I already knew would work better.
As it turned out when I eventually started listening I realised that his approach worked much better than any ideas I had so he taught me something new.
This situation comes up a lot when pair programming and I think it’s useful to always keep an open mind – that way you might learn something you didn’t expect to.
Grabbing the keyboard away
I think this one is more obviously ineffective and I don’t think I do this as often.
I did suggest in another post that getting control of the keyboard can be a useful way to help you become more engaged in a pairing session, it’s certainly useful to ensure that you communicate why you’re doing that and checking if it’s ok with your pair if you drive now.
On the other hand just grabbing the keyboard and typing without saying anything because you think you have a ‘great idea’ is not really an effective way of working together with your pair as it effectively sidelines them.
These are just a few observations of some things I’ve noticed and as always there are no doubt more ways that we can pair program ineffectively.
Pair programming for me is not just about putting two people together and having them work the same way they would normally – there certainly seems to be a completely different dynamic to the way we work and I think it’s important to adjust the way we work to adapt to that.