Sunday, May 30, 2010

Pair Programming in the Wild

Pair-programming is probably one of XP's most controversial practices, and that may have been one of the reasons I initially got attracted to it about 5 years ago. After all, sticking only to practices that are mainstream, will end up with mainstream results, yet studying out-of-the-box practices that may potentially yield a world's difference in productivity and quality, is like discovering an O(1) algorithm in comparison to O(n): big difference!

So, what is pair programming about anyways?

In a keynote presentation that I gave at the Agile Comes To You Seminar last week, I defined it as:
Two
 programmers 
solve
 problems 
together 
on

one 
machine:

  • The
 driver (person on the keyboard)
 focuses 
on 
writing 
code

  • The 
navigator 
focuses 
on 
strategic 
direction
Notice the emphasis on how the programmers "solve problems together" as opposed to write code together. In other words, writing code is not the bottleneck, solving problems is.

If writing code was indeed a bottleneck, then pair programming would have been a very different skill. It would have been about one programmer learning how to type on two keyboards at once instead of two programmers typing on one keyboard. It would have been about dedicating your left brain for one computer monitor and your right brain for another. It would have been about writing code that writes code for you. All of these things would have been interesting skills to master if writing code was the bottleneck.

In reality though, writing code is just a tiny concern in comparison to solving big programming problems for business. And, here are just a few examples of the problems I am talking about:
  • Where do I put the responsibilities for reporting on a collection of objects to make the code as maintainable as possible in the future?
  • What is the most efficient SQL query I can write to have the report run fast?
  • Do I need pagination or is the result set small enough?
  • Is it worth applying the State Pattern to this problem or are the state related actions few enough to warrant not applying the pattern?
  • Do I need a layer of presentation objects between the models and the view or would the code end up simpler without it?

I cannot emphasize how often I have spent hours on such problems on my own, only to take a break and talk to another developer, and then get an immediate solution from their point of view.

That made me curious about all the scenarios that benefit from pair programming:
  • Decisions related to code aesthetics/API often get resolved quickly when validated against another developer's opinion, finishing faster, and with clearer code.
  • When deciding on one of multiple alternative solutions to a problem, a developer working alone may hesitate quite a bit about picking what is best for the team. Having a second developer present provides more confidence and speeds up the decision process.
  • Synergy is the idea of 1 + 1 > 2. This can help a lot in solving problems that involve creativity. Often developer A has one solution in mind that is not optimal and developer B has another solution that is not optimal. So, leaving one developer to implement his solution alone may yield mediocre results whereas having the two developers discuss their solutions first may yield a new solution that is much better than the two original ones.
  • When solving a problem that requires multiple skills (e.g. OO skills vs SQL querying skills), it is common that no one developer on the team is the best in all of them. So, having two developers work on the problem will increase the chance of addressing all parts of the problem optimally, and at the same time cross pollinate the developer skills. For example, I have learned quite a bit from pairing with a developer who was proficient at SQL, while I helped him learn quite a bit about OO design.
  • When the driver spends too much time focusing on a problem that is of low priority, the navigator who has more of a bird's eye perspective will often notice that quickly and prevent the driver from getting derailed for a few hours unnecessarily.

Under the surface though, there are less apparent under-estimated benefits that improve developer skills and the development team quite a bit in the long term:
  • Having developers socialize while programming on a daily basis increases team bonding and commitment toward the success of the project.
  • It can be quite fun, thus greatly motivational.
  • When developers of different experiences pair together, they cross pollinate their knowledge, learning quite a bit from each other, and getting stronger in the long term. One example of this is the number of shortcuts I learned while programming with the Eclipse IDE on Java projects. I got to a point where I can almost do anything by keyboard without ever wasting time reaching for the mouse. And, whenever I paired with new programmers, they would get surprised by the number of shortcuts I knew, and tell me that it intimidated them to learn that many shortcuts. I had to explain to them that it was like watering a plant: I learned all my shortcuts a few shortcuts a week over 12 months of pairing with different developers, thus expanding minimal yet consistent effort.

Given that I am clearly sold on pair programming, does that mean I do it all the time? Well, there are cases when I avoid it for practical reasons:
  • I get exhausted from pairing for 5 hours straight. Yes, pairing can get exhausting, so it is important for a pair to realize the point at which they need to take a break from pairing.
  • I come to work tired from lack of sleep. I know I would not be effective pairing in that mode.
  • I have boiler plate work that is mind numbing such as data setup or the like. In this case, typing would indeed be the bottleneck, that can be a bad sign indicating lack of automation or having the wrong person do the job (developer doing the job of a data entry clerk).
  • I would like to work with a new technology on my own for a while in order to solidify my learning of it after having spent sometime pairing with someone on learning it.

So to summarize, pair programming is about synergistically solving problems, not just having two developers typing on one machine. As a result, the benefits are:
  • Increased productivity
  • Higher code quality, indirectly contributing to productivity in the long term.
  • Better solutions, indirectly contributing to customer satisfaction.
  • Increased team commitment
  • Continuous improvement to developer skills

Comments are welcome, especially to share personal experiences or ask questions about pair programming in the wild.

Monday, May 24, 2010

Writing good code is ALWAYS faster than writing bad code.

"No matter who. No matter what. No matter when. Short term. Long term. Any term. Writing good code is ALWAYS faster than writing bad code." - Uncle Bob

That was a recent tweet by Robert C. Martin who has been doing software development for more than 30 years and has written many books on the subject.

I couldn't agree more. In one of the projects I was involved in, I encountered some code that developers rushed out the door quickly in two weeks without writing any tests or paying attention to how clean the code is because they felt pressured by the deadline. Needless to say, it had many bugs, so it took much longer to fix all of them and truly deliver the feature than the originally planned two weeks.

The real irony of the matter though is I believe it would have taken no more than the two weeks originally planned if tests were written first. That is because without test-driven design, the code was bloated and much more complex than needed. When I later covered the code with tests and performed refactorings, I discovered that the original code was more than double or even triple the amount of code needed with a simple clean design. In other words, it took longer to write the code without tests, and that is not counting the extra time spent tracing and fixing bugs.

Instead, developers had to get embarrassed by the large number of bugs reported, spend a long time tediously tracing through complex code to find the bugs, scramble to fix the bugs quickly, and be delayed by a few weeks in truly delivering the feature. It makes me wonder what gain they got out of not test-driving clean code in the first place given that it was an Agile environment where everybody was already aware of the practice.

I bet it was the convenience of not having to change their ways or ignorance to the true practical benefits of test-driven development. And, I have to admit, during my learning phase of test-driven development, it took me a while of swinging between doing it and abandoning it before I started seeing the futility of not doing it and truly appreciating how faster I got in developing software that way.

To recap, I wholeheartedly agree with Uncle Bob. Writing good code is ALWAYS faster than writing bad code.