It happens quite often: the project deadline is approaching and the team has to go faster. On my last 2 projects we decided to apply pragmatic pairing to see if our velocity picked up. Sure enough it did, after all do we really need to pair 100% of the time? On the other hand how do we make sure code quality is maintained, and knowledge of the codebase is shared? That's how we introduced the concept of code preview. That's right, not review. Preview.
Out: code review
I'm not adverse to the concept of code reviews, I actually tried on several projects. In fact, before the days of mainstream-pairing they were a common technique for catching bugs and spreading knowledge of the codebase. But I have to say I never saw it working too well, or particularly enjoyed it.
They have to be communal
Many times I've seen "review" emails going around or source-control URLs being assigned. Unfortunately this make code reviews a solitary and impersonal exercise, when the essence of reviewing is communication. Without much context, it also means the reviewer can only skim the surface, pointing out trivial errors or naming conventions. This gives very little return on the time investment. Unfortunately the final effect is a team who dreads "code review Friday" and the recurring 1h booking in everyone's calendar. So what can we do?
One obvious solution is to conduct the reviews in pair, author plus reviewer. This takes time, but lets you dive a lot deeper in the process. The author gets a chance to explain the overall design, technical choices and algorithms involved. In reasonable time the reviewer can get some insight on how a feature was implemented - and in most cases form a mental picture on how they would have done it, or suggestions for improvements. However…
It's all after the fact
That's my major issue with code reviews: they happen after the fact. You just reviewed someone's code and have great ideas on how you would have approached the problem, or of a much simpler algorithm. How do you tell your colleague there are different (and maybe better) ways of achieving his result? Code reviews become a diplomatic exercise where we try to offer just the right amount of constructive criticism. And if all goes well, what outcome do we expect? The work has already been done - is it worth starting from scratch again? The point of not pairing was to increase velocity, so in many cases these remarks become post-it notes on a tech debt wall. So instead we point out trivial errors and naming conventions - and we've come full circle.
In: code preview
That's why we thought we'd turn the concept on its head. What if we code-reviewed in teams, and before the fact?
On most features (we exclude the trivial changes), a few team members get together and discuss the technical design, from high-level system impact to classes and interactions. It might take a while to find the right balance, we don't want these to turn into endless design battles either. Eventually you should find that half an hour is enough to agree on the general direction - and if not why not try concurrent engineering with multiple implementations? A great outcome can simply be a hand-drawn diagram or mind-map. If the feature is relatively big the team can even sign-up for different parts.
Regardless of how many people end up writing code for this feature, I still recommend that the "preview" team gets together at regular checkpoints. Every day, assess how the code is going and if we're still on track. The person writing the code can walk someone else through the classes and interactions, or explain complex algorithms. We found that most refactoring ideas and suggestions are accepted a lot better when they're minor course adjustments from the original plan, and when they come from someone who was involved in the original design. Conversely, all the other team members gain knowledge about the features being build, and this reinforces the collective ownership of the entire codebase.
On the next project…
Many good design or refactoring ideas on our current project emerged from code previews, so I'll definitely keep encouraging it. In fact we can simply introduce the concept as optimised pairing. In many situations the benefits of pairing obey the 80/20 rule, and code preview seems to focus on the 20% of time that really matters. There's a saying that went around our project, and it said:
if it needs a brain, it needs two. I couldn't sum it up better.
But this is not a recipe by any means, each project is different - so I'd love to hear what works on your team and how you juggle pairing, productivity, and code ownership!