Category Archives: Craftsmanship

Pair programming – is it worth it?

I was recently tasked with creating a “quality improvement” strategy for one of our projects. One of the controversial propositions turned out to be pair programming. How are we going to justify this cost to the client? That question caught me off guard. I didn’t even think that might be an issue. I didn’t even think about mentioning it to the client, too. For me it’s just a natural part of my work, like using CVS. I never had to justify doing that to anybody. In fact, it used to be quite the opposite.

Stage 1: I hate it

For me personally, pair programming was very challenging. It was the least favourite part of my work. I am a perfectionist (luckily, recovering one) and ever since I can remeber, I hated people looking over my shoulder when I was working on something. Even when I was in primary school and my mum wanted to check how my essay is progressing, I got aggressive. That’s the main reason why I always insisted on not having anybody sit behind my back. I hated the idea of somebody staring at my screen. What if they saw me doing something very dumb?

Over time, I got pretty good at using various avoidance techniques, altering aggression with jokes and plain refusal. Of course, I could got away with this behavior at home, but it wasn’t professional to say the least. Pair programming was not only allowed, but strongly encouraged by my team-lead when I worked at VSoft. I’ve also heard a lot about its benefits. Like it or not, since everybody around me was doing it from time to time (and I couldn’t really say no, every time they wanted to pair on some task), over time I simply got used to it.

Stage 2: I learn a lot

My first “real” pair programming experience was slightly over two years ago and I can’t believe how much has changed. I don’t mind other people looking at my code. I love it. Getting feedback is awesome. I like getting new ideas to improve my code during reviews. I got comfortable with criticism, use it to learn about different approaches and coding preferences. At the same time, I learned to defend my point of view, discuss the motivation behind the decisions I made and be ok with changing my mind, when reviewer points flaws in my thinking.

I can’t recall specific words, I don’t remember all of those small and big ideas I learned through pairing with other people. Some of them applied only to the situation at hand. But there were a few that I benefit from today, such as testing untestable code (thank you Lukasz for being such a pain in the neck about it, now it’s second nature:)), getting familiar with all the crazy shortcuts, learning about new tools, etc. I’m also much better in giving feedback to sb’s code and learned a lot by thinking hard how their code might be improved or why something “didn’t feel quite right”.

Overall, once I got over this irrational “don’t you dare look at my code” attitude, my rate of learning went up significantly. Besides, I think that my productivity was higher, when I worked in a pair, because I was fully focused on a task at had. There was no email checking or talking to colleauges. I did my best not to waste somebody else’s time. Unfortunately, I don’t have any hard data to support that claim.

Stage 3: It’s not a silver bullet

When people ask whether pair-programming is good or not, I think the only honest answer is (of course) “it depends”. There are some people I can’t pair with. When we tried working together it was simply counterproductive, because we just kept arguing and nothing got done. Working with some others was challenging, but I learned a lot. Finally, when working with some people I felt that magical synergy, we were more effective together than each of us working separately, because our working styles and our typical focus areas were complementary.

So it depends to large extent on whom we work with. It’s good to get out of our comfort zone, but I think that pushing through, just for the sake of activity when it’s clearly not working, doesn’t make any sense.

Then it depends on the task at hand. When the task is a no-brainer or we’re very familiar with the area of codebase we’re working on and we’ve done similar tasks before, then pairing might be a waste of time. For me it was most beneficial when I worked on something very new or especially complicated. I could have asked for a review afterwards, but pairing seemed to be more efficient way than stopping every now and then to discuss my idea with a colleague.

Stage 4: It’s hard to work otherwise

There are two situations when pairing seems to be great, irrelevant of other factors. The first is introducing a new person to the project. I can’t understand why people don’t see how wasteful it is to give a vaguely described task to the newbie and instructing them to “ask when they need anything”. Even if they are experienced developers, it takes some time to understand business requirements and be able to understand the impact of every decision on other areas. We lose opportunity to make sure early on that they follow our interal standards and practices. Not to mention the frustration they experience, when they happily announce their task is finished, only to be told that they have to re-do it because of some stupid catch they were unaware of (happened to me recently a few times, extremely frustrating experience).

The other situation is making significant changes or working on some complex piece of logic. It’s beneficial to discuss our design ideas, pay close attention to implementation, make sure we don’t make stupid mistakes, that can be avoided by using second pair of eyes.

For me the main benefits of pair programming are exchange of knowledge between the devs (both domain specific and regarding tools and skills) and avoiding painful surprises during reviews or testing (Oh, how could you miss that edge case? How could you not know about this email I sent to XYZ half a year ago? Why don’t you know about our super-secret document, where all this is described? How can you not know that some external app relies on this file being in that location?).

At this moment, I can’t think about any more efficient and sustainable practice for continuous quality improvement and spreading knowledge among team members.

Stage 5: Back to square one

So how do you justify to your client not doing it? Is there any more efficient way for achieving the goals I’ve just mentioned (improving quality, mentoring, sharing knowledge, avoiding bugs)? Is pairing something one should discuss with the client? Should client be allowed to make such decisions for us?

For me the only honest answer is that I can’t justify not doing it. The other ways for konwledge sharing and keeping high standards that I know, are not as effective (e.g. workshops, presentations). Code reviews should be enough for ordinary tasks in an experienced team, but even for them, I think the two situations mentioned in Stage 4 are still relevant. When it comes to clients I believe that it’s my job to be the best professional I can be and client shouldn’t decide on standards in our industry.

I think this is true not only for software. For example, I don’t go to the dentist and tell him he shouldn’t have an assistant, because I have to pay more for the service. I trust that they do their job well and that this is the best industry practice. I also suppose that if they worked alone, the overall cost would be much higher, they would do the same task longer with more mistakes and caused me more discomfort. Better service for less money? Even if not true in every case, I think this is more common than most people realize.

Legacy Code Retreat

Recently we  (together with Seb) organized a Code Retreat event in our company. It was not the typical event you see during Global Day of Code Retreat, for a few reasons. First of all, it was internal, only people from our company were present. Therefore, the diversity of tools and languages was not as high as usually. Then, it was organized during work hours. Finally, it was a Legacy variant.

What exactly was the point?

Some people might question, whether organizing internal company event of this type makes any sense. After all, one of the fundamental rules of retreats is attending them in your free time, only because you strive to improve your skills, not because your employer requested it. In our case there were a few reasons for choosing that format:

  • We knew there are a few skills that devs from our company needed to improve (refactoring, following simple design rules, writing tests and testable code, etc.). We knew exactly what issues come up in various projects and decided that getting familiar with those basics is the first step towards making our codebase better.
  • We didn’t have any training budget, therefore we couldn’t hope for getting a professional trainer. Even if we did, probably it wouldn’t be worth spending that money for learning the basics we intedned to cover.
  • Many people work long hours, so asking them to do something extra in their free time seemed a bit too much. Even then, getting some people out of a project even for one day turned out to be extremely difficult, so we needed an official, approved event to allow people to spend some time learning.
  • We wanted to provide opportunity for people to practice new skills. Making a presentation, organizing a “Lunch and learn” or anything of that kind, for sure wouldn’t work for us.

What did we do?

  • We’ve got source code for JBrains’ Trivia game from here. We paired with Seb for one hour to get GoldenMaster done, in case some people don’t finish it during first session (proved to be useful:)).
  • We organized a short intro to Git a day earlier (especially useful for short refactorings session).
  • We run sessions, each 45 min., followed by a retrospective and break. Since retros between sessions were very short, not everybody had to answer questions.
  • In the end we asked every person to share what they learned, which session they liked the most and what will change in their work from next Monday.
  • After that we hit the pub for a quick beer:)

How did it go?

We were surprised and very glad when people said how many new things they learned from each other. Without any suggestions on our side, a few people said exactly the things we wanted to address, regarding changes in how they would work from now on. People also got very excited about what they learned, some encountered new tools that their colleagues were using, seems like the event left them hungry for more (which was one of our two main goals).

Of course, work is much harder than what we do during reatreat, in reatreat we don’t have databases, codebase is tiny, we don’t worry about deadlines and pressure from management.  So I’ll follow up on this, want to see whether people managed to implement those new ideas at work and what challenges did they hit.

Detailed description of sessions:

Session 1 : Golden Master – Create a test for the game, changing as little code as possible and covering the largest possible number of cases (challenge – change only one line). Keep the tests and use them in later sessions.

Retrospective questions:

  • How much did you change?
  • How many test cases did you cover?
  • What challenges did you hit? How did you deal with them?

Session 2: “Make the code better” – Using whatever techniques you’re familiar with make the code look better (whatever that means to you)

  • What do you think about this codebase? What problems did you hit?
  • How did you change code (e.g. extracting methods, extracting classes, removing duplicates)?
  •  How many tests did you add?

Session 3: Pure functions – Extract methods that do not have any side effects and state.

Retrospective questions:

  • How many methods did you extract?
  • What methods did you extract?
  • How many tests did you add?

Session 4: Single responsibility principle – Make sure each class has a single responsibility.

Retrospective questions:

  • How many classes did you extract?
  • What classes did you extract?
  • How many tests did you add?

Session 5: Short refactorings – There’s an imposed 3 min. limit for refactoring and covering your change with a test. If you don’t manage to finish before time elapses, revert your changes.

Retrospective questions:

  • How many refactorings did you manage to finish?
  • What did you learn in this exercise?
  • Did you use Resharper and keyboard shortcuts?

Session 6: No mouse or short methods or eliminate conditionals – Pick one of the three tasks (or combine them:)): either do not use mouse or eliminate conditional statements from your code (ifs, switches, loops) or make your methods shorter than x lines.

Retrospective questions:

  • Which task did you choose?
  • How many conditionals did you eliminate?
  • What techniques did you use (popular ones are using dictionaries or modulo function)?
  • How many methods did you add?
  • In the end, how many of your methods were longer than x lines?
  • How many tests did you write?