I've recently started a new contract where we do 100% pair-programming. This is the first time I've done pair-programming on anywhere near this level. In the past, I've only ever paired on an ad-hock basis either to help someone else solve an issue, or vice-versa. This is an 8-hour per day contract, where other than meetings, we're pairing for all of those 8 hours. Sounds full-on? Well, actually so far, it seems to be working pretty well! Obviously, it makes a huge difference who you're working with, and I've been lucky that I seem to be getting on well with both developers that I've paired with, and we seem to think in the same way and haven't hit any conflicts so far!
It's worth pointing out that this is a 100% remote team, regardless of the current COVID situation. I'll compare this with the limited experiences I've had pairing 'in-person' later in the post. I'll also discuss some tooling that we use.
I'm going to start by talking about the benefits, which I'm finding, far outweigh the cons...
I've worked with a lot of companies during my career, but I've never worked for one where there hasn't been large areas of code solely known by just one developer. This is obviously bad if/when that developer leaves, either making their code a no-go zone, or causing a lot of lost time whilst other developers have to pick up the code with no context of reasons some decisions were made.
When work is done in pairs, there's always more than one person who understands each area of code.
Pair programming takes rubber-duck debugging to the next level! Rubber-duck debugging is where a developer explains the problem to someone else (even if it is just to a rubber duck!), and the mere act of articulating the problem helped them realise the issue. With pair-programming, everything is articulated! Not just bugs and issues, but all code decisions.
As part of these discussions, architecture will most certainly come into it. All developers have different backgrounds and ideas, and the discussions around different possible solutions can create much better, more thought-through architectures - saving a lot of time in the future.
Two eyes (brains) looking at code being written are far more likely to spot mistakes and potential bugs, than a single developer just typing away. I'm seeing many changes a day being made due to one of us picking up something that the other didn't spot or think about.
Being a new member of the team, it's really been apparent to me just how much faster pair programming has helped me pick up both the architecture and codebase. Anything I'm unsure about, I can just ask as part of the conversation we're already in anyway. I'm not interrupting anyone to ask questions as we're pairing together anyway. And it's so important to ask questions. Always remember, questions create far deeper understanding. Never ever be afraid to ask questions!
If new developers are just given tasks and left to it - there's a high chance that it might not conform to the standard design patterns that the team tends to adopt. Unless the codebase really enforces the chosen design patterns, then an codebase that isn't brand new, is quite likely to be a bit of a mess with various different ways of doing things. This is something that pair-programming can help mitigate against. A new developer can be introduced to the patterns and practices that the team has adopted whilst pair programming. Even if you decide that pair-programming long-term isn't a good fit for your team - it's definitely worth doing initially with new starters.
I mentioned at the start of this post that I'm now working with a 100% remote team. So all the pairing I'm doing is obviously also 100% remote. Has this been an issue? To be honest, I've actually found it easier than pairing in person. Whilst in past companies, I've only paired ad-hocly, so perhaps not the same as an official in-person pairing setup - it has always involved one of the pair not being at their own computer. I don't know about you, but my setup is quite customised. From the hardware where I'm used to my own keyboard/mouse, to software - I use Vi; have various tools and utilities I jump to improve my productivity; my hotkeys are setup how I like them, etc, etc. If I'm using someone else's machine - it's a very unproductive experience. Remotely, each developer is using their own machine, and is free to lookup related stuff on the internet, navigate the code separately if they need to, etc.
We use Teams for communication, where we primarily use it just for calls rather than text. We take turns "driving" and sharing our screens, which seems to work quite well when pairing.
I mentioned in a recent blog post about working from home about the importance of having decent audio. Near the start of the lockdown, I invested in a decent microphone (Blue Yeti X), and am so glad I did! I made the investment because I knew I would be working remotely for some time, and would be hosting .NET Oxford virtually for some time too. I'm also planning to start a podcast, so this was the ideal opportunity to invest in decent hardware. However, I didn't realise at the time, I would be literally talking all day long through it for pair programming. When working remotely, audio quality makes a huge different - so is definitely worth the investment.
If you're a Visual Studio or VSCode user, then Visual Studio Live Share is definitely worth looking into. My primary IDE is Rider, which sadly doesn't support it - it would certainly be nice if the protocol became an open standard that could work across other IDEs!
For those that don't know what Live Share is - it allows one person to host a session, which others can join. You can then all edit the same code, and you can see what the other person is doing. Think of Google Docs collaboration, but in your editor when coding.
(image taken from Microsoft's website)
You can even toggle whether you're 'following' another user, which will automatically navigate your view as they move around the codebase.
Whilst this is amazing tech, there are downsides. My biggest problem is that as the participant (ie. not the host), you lose a lot of the IDE functionally. Especially if you use Resharper. I find that intellisense no longer works, and navigation shortcuts stop working, etc. Another issue is that you lose some context of what the other person is doing - you can't see their intellisense or popup dialogs. So for example, if the other person has a dialogbox up to rename something, and is thinking about what to rename it to - the participant can't see that dialog. Also, if the other person switches to another application - eg. OneNote, SSMS, LINQpad, etc, you obviously can't see that either.
I do find it useful to have vscode with live-share in a secondary monitor though - so I can see the screenshare in my main monitor, giving me full context of what the other person is doing, whilst still being able to edit code in vscode via live-share.
I think the biggest benefit I get from Live Share rather than screenshare, is that I can scroll around the modified code independently of the driver. When pairing, we tend to take turns driving and being the main person coding. Obviously the person driving, is scrolling up and down and moving around the codebase. This makes it hard to follow along, if I'm trying to read the code. I quite often want to be able to scroll around independantly. Whilst I can navigate already pushed code locally on my machine anyway - I obviously can't see modified code that the other person hasn't yet pushed. But through Live Share, I can.
Another advantage to LiveShare over screenshare, is that you can choose font-sizes, etc. Sometimes I find screenshare can be a little bit blurry - especially when our screen aspect-ratios aren't identical. Looking at the code in VSCode via LiveShare much clearer.
I've talked a lot about the positives of pair programming so far, so here are a few negatives...
When solo-programming, I have my headphones on with music, and really get into the zone and find I can focus quite deeply. When pairing, I'm never really getting into this state. That's not as bad as it sounds, as it's been replaced by a state of discussion which has plenty of other benefits as described above - but I do miss having periods of time where I can code to music and get into a state of deep work.
I've been quite fortunate in this new contract. Both developers I've paired with so far have not only been really good developers, but also great to get on with too. It certainly hasn't felt like a long day pairing for 8-hours solid with them. However, if you were forced to pair all day with someone you didn't get on with - after all, some personalities do clash - I can see that not ended well at all. Managers, please bear this in mind when deciding who should work with who!
When first explaining pair-programming to someone, the usual reaction/question is "but doesn't this cost twice as much in resources?". Hopefully after reading this post, this clear answer is 'no'. The quality improvement you get from all the things I've discussed; plus mitigating against someone leaving without anyone else knowing their area of code; plus the team bonding, and additional consistency of design patterns you get in the codebase - more than outweigh the cost of two devs working together on work items.
A couple of years ago, I wrote a blog post about using Pull Requests in the workplace (link). I wrote that post because I had recently started working with a team that used PRs, and this was the first time I'd worked for a company that did this. I'd used PRs for open-source, but not in the workplace itself. It feels like pair-programming takes the benefits I describe in that post to the next level!
I'm enjoying pairing in this new role, and feel I've learnt the architecture, codebase, and the team's 'ways of doing things' much faster than I otherwise would have done. Plus, I feel I've gotten to know the team much better than if I'd been working solo on tasks from a backlog (remember, this is a 100% remote team).
One thing I would say, is that I'd recommend having at least half-an-hour a day soloing. This allows you to be free to browse the code-base and digest other areas of code.
Do you have experience in pairing? Has it been positive or negative? I'd love to hear your thoughts and experiences on this, so please do comment below, or feel free to reach out to me directly.