Archive for June 2011
…or how I learned to stop worrying and love deleting the code.
Yesterday I had a great opportunity to participate in a very enlightening and thought-provoking activity, named Code Retreat, in Düsseldorf! It was smoothly conducted by Daniel Temme and Adrian Bolboaca and hosted by codecentric AG. The idea of the code retreat is very simple: use TDD and Pair Programming technics to automate Conway’s Game of Life in sessions of 45 minutes …but delete all of your code after each session!
What?! Delete code?! But how am I supposed to get the job done?
The point is not to get something done, but to exercise the technics of test-first development and simple design. This looks silly and pointless at first and is indeed really hard.
But it all look pretty simple at first. In the first session my pair and I haven’t even come to the game rules. We started with some examples, that we represented as strings. Then we were writing a parser, that would take string representation of the game grid and provide a two-dimensional array with Boolean flags, indicating life, so that we could feed our examples into the game engine. It seemed a logical top-down approach to me at first, but proved itself meaningless.
After the session we all together discussed any findings and ideas that we got out of the session. Adrian was provoking us with questions like: Why do you need an array? Where this Cell class came from? etc.
So the next session we changed pairs (this is a rule of Code Retreat) and started all over again. This time we focused on game rules, test naming and abstractions, but were still unable to make very small baby steps with our design. Abstractions just spawned out of nowhere (out of our head, actually) and made it right into the code. We discussed it after the session and decided to treat the imaginary design obsession syndrome with a very restrictive diet…
TDD As If You Meant It
- write exactly ONE failing test
- make the test from (1) pass by first writing implementation code IN THE TEST
- create a new implementation method/function by:
- doing extract method on implementation code created as per (2), or
- moving implementation code as per (2) into an existing implementation method
- only ever create new methods IN THE TEST CLASS
- only ever create implementation classes to provide a destination for extracting a method created as per (4).
- populate implementation classes by doing move method from a test class into them
- refactor as required
- go to (1)
Despite of the simplicity of the rules, it’s very hard to follow them. But it works. Design gets in fact much simpler and it really gets derived from tests.
We did 6 sessions during the day. I programmed 3 times in Java, 2 times in C# and one time in Ruby. Switching languages is great exercise in itself. No matter what language, testing framework or IDE/Editor we used – the most important concern was to understand the problem domain, codify it in tests, and let simple design solve it.
Throwing out code is not only useful as an exercise. I can imagine a Code Retreat workshop as a way to understand a very complex core domain (in DDD sense) in productive development.
After the event I felt exhausted and energized at the same time. I realized that I barely did any TDD before, but I learned where to start and how to proceed my learning. All in all it was the densest coding activity I ever had. Really look forward to participate in another Code Retreat soon and will do my best to organize the next one in Düsseldorf!