What I’ve learned from J.B. Rainsberger and Corey Haines

I had the unique opportunity to spend about a week with J.B. Rainsberger (website and second website) and Corey Haines (website), in what proved my best learning experience of the last few years.


I’ve learned many things in the last days, but here are a few of them:

Knowing the tool is paramount for productivity

During the TDD class, J.B. made a demo of emergent design, called “Architecture without trying”. The first thing everyone noticed was how fast he was programming and how he used effectively all the features of the editor (in this case, Eclipse).

How to get there: unplug the mouse and learn fast typing, until the fingers do all the mechanical work.

Care about the code

Refactoring continuously will make the design better. When refactoring, two rules are important: everything (methods/procedures/functions, variables, classes etc.) must be named precisely and duplication must be removed as much as possible. Hint: duplication is also present in names (a1, a2, a3 is duplication – besides being an imprecise name – because the letter ‘a’ repeats).

For more details, J.B.’s articles on the four elements of simple design and why he names things precisely are wonderful resources.

Learn to refactor

Martin Fowler’s book on refactoring has exercises on how to apply each refactoring method at the end of each chapter. Practicing those exercises is an excellent way to effectively learn refactoring.

I can safely say that I have a lot of experience in refactoring, but what I learned is that it’s important to master the “mechanical” side of refactoring, meaning all the small steps one can take such that after each change the code still works. Taking small steps is hard.

To learn TDD, learn Test First Programming first

TDD is hard. Test First Programming is the natural first step towards TDD. The difference between the two is that for TFP design happens before writing the tests, while in TDD the test drives the design. After a certain time of TFP practice, moving to TDD comes more easily. Another tip is to mock by hand at first. I’ve made the mistake to try using a mock framework from the beginning, and I soon realized that something was wrong. The typical thing is that it’s easy to mock chained calls (first.second.third) in a framework while when doing it by hand is painful – so mocking by hand has a more powerful drive towards refactoring.

TDD bears many similarities with the scientific method

The TDD steps are: make an assumption about what should work in the system, write a test that verifies the assumption, write the code that passes the test (thus implements the assumption) and refactor. The key is to go in small steps, such that the assumptions are built incrementally and the code passes only the current assumptions.

The scientific method (explained here) has at its core the following steps: observe a phenomenon and question its cause, create falsifiable hypothesis regarding phenomenon’s cause, attempt to falsify hypothesis, if falsified form a new hypothesis, if validated confirm it through other means (more tests, peer review etc.).

The difference between the two is that TDD focuses on obtaining a specific result whereas the scientific method focuses on discovering more about a system. The similarities lie in the way a practitioner must treat the assumptions about the code.

Work in small steps

When doing TDD, small steps are the key. Small steps are annoying at first because it seems that programming is much slower than before, but this is only an impression because the work includes some design, writing code and some testing. The rhythm is constant and it’s very fulfilling to see that something new is added at each step. After enough practice, the steps that at first seem very slow are performed in a very quick succession (especially after lots of practice using the full capabilities of the tool, keyboard only, and the refactoring patterns).

TDD is not for everyone and everything

It’s OL not to use TDD. As a professional, I believe you have the duty to try it and see if it works for you. But there are people who may decide it’s not useful, and the only thing I’d like to know is why.

After drawing my conclusions, I decided to take actions:

  • I will learn the tool I’m using every day and use it without mouse
  • I will practice TDD using the problems from Project Euler
  • I will use TDD for my projects (I used to but not all the time)
  • I will re-read Martin Fowler’s Refactoring book and practice the exercises.

For more information about how you can learn TDD, try looking on the AgileWorks – the Romanian Agile community – website.