Posts Tagged ‘coderetreat’
Last Saturday was about the second Global Day of Code Retreat for us with DeVill and 15 other developers in Budapest, when more than 3000 developers in 160 cities came together to practice the basic moves of programming, or software craftsmanship if you like, just like painters, musicians, dancers and martial artists do, by pair programming with developers they never met before.
Last year, when I participated in the first event organized in Budapest by Meza, I wouldn’t have thought that I would be a facilitator of the next one. It was awesome to be part of the event! When I went to sleep on Friday, the first coderetreats of the day were already started, so it was very hard to get into the bed while the first #gdcr12 tweets were appearing on Twitter.
This event was a special one. Not just because this was the first code retreat in Budapest where girls attended as well, but because during the day we waved to fellow developers at Zurich, Nuremberg and London through Google Hangouts, all of these locations having at least one organizer or facilitator from Hungary! (We also tried to say Hello, but some sound issues kicked in. )
And again, just like in earlier code retreats, I learnt a lot. For example, that you should be very careful with your hotkeys and typing when programming in a language that supports unicode characters in identifiers, like Java or PHP. An invisible character somewhere, and your code is screwed for seemingly no reason! (Imagine what level of code obfuscation could be reached by using a RTL marks!) Someone mentioned during the closing circle that he starts every morning with a 20-25 minutes coding kata, which is a great idea I’m going to adopt as well.
Thank you everybody for this day, I can’t wait for the next one!
Last week of September was about Code Retreat events for developers and test engineers at BalaBit. During the week we had internal Code Retreat days facilitated by Nucc and me to let everyone learn and practice the basics of Test Driven Development and handling legacy code, without the pressure of everyday work deadlines. On Saturday, September 29, BalaBit hosted the 4th event of Code Retreat Budapest (or 5th if you count last year’s Global Day of Code Retreat), with DeVill and me as facilitators. What surprises me at every Code Retreat I happen to participate in (in other words: all of them in Budapest (-:) is that you can always, always learn something new, no matter how many CR sessions and events you’ve attended.
To let participants focus on the techniuqes themselves, the job at a Code Retreat is always to implement the business logic of Conway’s Game of Life. There are 45 minutes long sessions during the day in which participants have to work in pairs, followed by short retrospective meetings and selection of a new pair for the next session. And of course, the code is deleted at the end of every session so the new one can be a green field project again. The problem usually becomes well-known by the second or third session, that’s when intensive learning can begin by introducing new constraints and concepts in every session.
Free hand session
The first session is typically free hand. The goal is to get familiar with the problem. Most of the time this session makes two kinds of developers emerge: UML-makers and test-drivers. The first kind typically spends a lot of time on designing a Death Star that is able to simulate Game of Life as well, and end up having coded nothing more than a simple data structure or a factory. Test-drivers usually write a few, sometimes a little bit complicated tests first, then write a few methods in the production classes, then debug for some time, then end up with a completely blown-up code base when the test for the next requirement to be implemented breaks everything that seemed to work until then. Most people don’t get to implement a single rule of the game, which is quite interesting, since the game does not seem to be that complicated at first glance.
Baby steps and TDD
The promise that TDD advocators often tell is that if it’s done right then debugging times can dramatically shrink. Since you are always a couple of minutes away from a green bar, it’s not a big deal to revert all your changes to that point in case you got into trouble. However, if your steps become too large, you may find yourself tens or even hundreds of code lines away from the last working state, so when you encounter an unexpected failure, you either throw away serious amounts of work, or you fire up your debugger or begin to add
What is often hard to get the idea of is faking implementation. Why would anyone write
return 0 just to pass a test, knowing that it will be overwritten in less than a minute? Aside from practicing the thought process, it’s similar to stubbing database layers in test harnesses: there’s something that’s out of your test’s scope. Real database setup and communication can make tests run slow, and anyways, when you’re testing your business logic, you don’t really want to test your 3rd party ORM tools and database adapters at the same time, otherwise your test failures won’t be able to tell which layer of your application may be broken. Fake implementations are somewhat similar to that idea: you use stub implementations (temporarily) in parts of the code you are developing that are out of the scope of tests written so far or don’t really belong to the abstraction you are working on.
For example, in case of Game of Life, it’s a good idea to write a test for the first rule first: this rule states that cells with less than two living neighbors must be dead in the next generation. The test will place a lonely cell and one with only one neighbor on the map, then produce the second generation and assert that all three cells are dead in that generation. Returning an empty array in the production code can make all those assertions pass. Since such a simple code can pass this test, it must be either wrong, or it is not really testing death of cells, at least at this point. The latter idea seems to make more sense, and if you think about it, the short-term value of this first test is a demonstration of the interface of the class under development. Looking at this first test, you may decide to make the interface more simple, rename some methods or experiment with other metaphors, etc. From this point of view, any more production code than what is enough to demonstrate a return value of a method may be considered out of scope.
The second rule states that any living cell that has two or three neighbors must live on to the next generation. The test for it may set up a configuration in which all the cells have two or three neighbors and assert that all of them survive. You see it fail, then write a loop that puts cells from the previous generation to the next if they have 2 or 3 neighbors, but how do you know the number of neighbors? Now you could write another loop to iterate over all the neighbors of a cell and increment a counter inside an
if statement that verifies if a neighbor is alive, but that together means at least two loops and two if statements for just two tests. Game of Life is simple enough to write all that code at once in seconds without errors, but the job is not to write a working Game of Life but to explore techniques and mindset often associated with TDD, so let’s find an even smaller step instead! One might write a method that counts neighbors and make it return a value derived from the total number of cells on the map for example. This can make the second test pass by adding a loop and a conditional implementing the logic needed to make cells survive depending on the number of their neighbors (but not on the neighbors themselves nor on their position nor on anything else), forming one layer of abstraction, and a fake implementation for a different abstraction layer (ie. the neighbors). If you like, that stub for neighbor counting can be viewed as a degenerate neighbor counter that consideres every cell on the map a neighbor to each other. Test for the third rule will encourage you to replace that fake neighbor counter to a real one anyways. Until then, you have the fewest code possible, making it easier to refactor if you feel that things are going to a wrong or unnecessarily complicated direction. The less code you have in your way, the easier is is to spot and restructure the parts you don’t like.
2 parameters, 3 lines
These constraints are about simplistic, concise code. It’s nearly impossible to write code meeting these constraints at the first time, so you are encouraged to get there by refactoring. Doing so you might find that extracting a few small functions and making complicated ones to be compositions of those can enable nice functional programming tools, and also get a glimpse on what and when to extract, since following such rigid constraints blindly can lead to a code that is more obfuscated than clean. Applying the same restrictions on the test code can remove all the duplication in it as well, making the test less sensitive to even big changes in the structure and API of the production code, which is a good idea anyways. If your tests are in the way of refactoring, you loose all the benefits those tests were made to enable in the first place.
Agile software development promotes the idea of responding to changes quickly and safely. Thoroughly unit tested code makes this possible by letting you refactor without fear before implementing a new requirement so you can add it to the system conforming to the Open/Closed Principle. New features are implemented by adding new code, not by patching and duct taping existing modules, right? Of course such a flexible architecture that enables that is impractical, if not impossible to create, but after an educated refactoring based on the knowledge of new requirements, you can nicely conform to that principle after all. To demonstrate the concept of such evolutionary design and how test-driven code can help during that process, we’ve come up with the idea of CR sessions involving unexpected requirement changes. Such a session is typically a longer one, we usually join the two last sessions for this experiment. During that we wait for participants to get close to a finished implementation of the Game, but before that could happen, we introduce a new requirement, for example, the age of cells, configurable rules, weight of cells inherited birth-time from the three neighbors, sometimes even hexagonal cells. Implementing any of these can be tricky in an architecture that was not designed with these features in mind and is obsessed with language primitives all over the place, but after isolating some behaviors, extracting relevant responsibilities or introducing new layers of abstractions, they are almost trivial to implement.
Unnecessary coupling and the lack of tests can make any code extremely hard to maintain. To learn the basics of getting bad code under test and then refactor it to be able to add features is quite hard to do during everyday work, but at a Code Retreat, people can safely experiment with it. That’s why I created this horrible implementation of the Game for our internal Code Retreat. It has a loop that can easily become an infinite one, it prints on the console, there are copy&paste snippets here and there, and to make things worse, it often employs bad naming and some overcomplicated helper methods. And we wanted new features in this mess that affected both the code responsible for applying the rules of the Game and the printing logic as well!
Most pairs find out quickly how to get rid of the infinite
while loop in
evolve() and how to isolate printing and the string representation of the Game’s state from the main logic, and after a few trivial changes, they could easily get the code under test. Some pairs even started by safeguarding those initial dependency-breaking refactorings with end-to-end tests so they were covered from the very beginning. In the end, many of the pairs managed to get a code base they could work with and test-drive the new features in, but for example, those who attempted to rewrite the code from scratch, had a hard time doing it and still failed, and to make things worse, they had painful debugging sessions as well. Imagine how rewriting code you don’t understand can fail if rewriting one that implements well known requirements fails so badly!
I can totally accept that some people still don’t like the idea of TDD and the quite unnatural ways of thinking associated with it and with evolutionary design. I just don’t want to end up integrating or maintaining their code.
I would like to say thank you to all the people at BalaBit who have a positive attitude towards learning and practicing the craft this way, and of course to all the craftsmen at Budapest who sacrificed a Saturday for practicing their profession! Meet you on the second Global Day of Code Retreat, on December 8th! And of course, greetings to fellow developers in London, who were also honing the craft on September 29th.
Do you think it’s funny to implement Conway’s Game of Life for the 20th time? According to my experiences, the answer is hell yeah!
Since the Global Day of CodeRetreat event (organized by Marton Meszaros in Hungary), I’m a big fan of the CodeRetreat format of coding dojos. I’ve been attending all the events of the CodeRetreat Budapest Community, and at the last one, I even helped coaching during some of the sessions. Nucc and me decided to introduce this event to our fellow developers at BalaBit as well and fortunately the management was kind enough to support us by dedicating some working hours to learn about TDD and other modern software development methodologies.
At a CodeRetreat event, you always implement the four rules of Game of Life (without UI and such fancy stuff). Doing the same task again and again makes the problem well-known and understood so you can focus on the style and design of your tests and code, which is the goal of a CodeRetreat. You don’t have to finish the implementation, though, it’s not about Getting Things Done or competing which pair is the first to finish. More like Not Getting Things Done. Often it’s impossible as well to finish for you have only 45 minutes to work. After that, well, code is deleted, a short retrospective meeting is held then a new session begins. Pair programming is mandatory, and by changing the pairs after every session you’re guaranteed to learn a lot from others. To make sure that you won’t be able to train yourself during the day to finish new constraints are introduced in every session, like infinite grid, immutability of states, 3 line methods with at most 2 parameters, no-mouse (did you notice you go faster when you use only keyboard shortcuts in your IDE?), etc..
During the first few sessions, there are no constraints. The goal is getting the problem understood. In the implementation, you just do whatever you want. That seems to be the hardest constraint though, since people tend to not finish during the first sessions. Instead they do Big Design Up Front and forget to care about the software to be implemented. These are the sessions where nice UML diagrams about
Neighborhood relations and
Rules and such nicely designed stuff are drawn, then people realize after 45 minutes that they spent almost an hour working on getters and setters but not a single rule of the game got implemented. Yep, there’s a reason for the Four Rules of Simple Design having been invented.
Turns out if you’d started the very first testcase with the first rule (“Any live cell with fewer than two live neighbours dies, as if caused by under-population”), you might have had a working implementation of all four of them after 15-20 minutes or so. And nothing more than that since you wouldn’t have written code that is never used except for making those UMLs feel more complete. YAGNI!
Of course there’s a chance that such a quick and dirty implementation will be, well, dirty. It may contain at least one thing you consider ugly. But you have more than half of the session left and the safety net of a bunch of tests to refactor the hell out of it!
You spoiled the public interface of your
Game with methods that should belong to a class named
Map instead? Are you feeling the need to test a method that is declared
private? After extracting such methods into a separate class, you might end up with a
Game class that has no state at all and contains only one public method that just creates new generations of cells based on a previous one.
On the other hand, after realizing how over-engineering slows them down, many people try to continue with sloppy design, skipping the refactorings for example to get rid of language primitives in the most abstract levels of the business logic or to conform to the SOLID principles, etc. They can be forced to do so by introducing requirement change surprises. For example, to handle hexagon maps along with square grids, a
Topology or similar interface has to be extracted from the class representing the board, which can encapsulate the details of coordinate systems and neighborhood relations between coordinates. (Did you notice that the rules of the game do not depend on the placement and shape of the neighbors nor the neighbors themselves, but only their count is what matters?) To handle colored cells which know how old they are, cells have to be represented by a separate class instead of bare coordinate-tuples or boolean flags.
Such refactorings can be a pain in the ass when tests contain copy&paste, duplication, redundancy and duplication, so they must be cleaned up as well: by extracting common fixtures, creating abstract assertions based on the repeating patterns of similar assertions, etc. (Abstract assertions even help you to conform to such rigorous principles like “1 assertion per test.”)
Imagine your day to day software development work boiling down to such simple business requirements implemented by a couple of short but well named methods in a few simple and minimalistic classes, all of them thoroughly unit tested (by unit testing I mean unit testing), all of those tests proven to be useful (since you’ve seen them fail and turning into green a couple of seconds later) and providing 100% coverage of assertions. Wouldn’t it be easier than digging yourself through stack traces in mindblowingly complex codes full of nested infinite-but-conditionally-breaking-somewhere-in-the-middle-do-while loops depending on side effects of getter functions and badly named global variables coming from a dozen layers away? If you know this feeling I’m talking about, I’d recommend you to visit the next CodeRetreat near your location (look around in Twitter or Facebook) – to try something new!
Saturday Nucc and me were attending the Global Day of Code Retreat 2011, Budapest event (#gdcr11) invented by Corey Haines and brought to Hungary by Marton Meszaros. In short, it was great fun and I hope that little community I met that day will come together frequently.
In more detail, Coderetreat is a coding dojo based on Conway’s Game of Life. In 5 or 6 sessions, each taking 45 minutes, you write code with your pair in order to translate the rules of the game into a working software. It does not have to display the board on a shiny UI, no animation has to be rendered, making all the tests green is just enough. Knowing you must delete all the code at the end of each session and that 45 minutes is rarely enough to finish implementing the game with full test coverage (and additional constraints you are free to pick), you can concentrate on the code quality itself: encapsulation, good naming, SRP, TDD, KISS, functional programming, or whatever skills you want to practice and develop.
After each session, code is deleted and a retrospective meeting is held where everyone can tell others what was learnt and what needs improvement during future sessions. Of course, during the whole day, your social skills get improved as well: pairing with unknown people, working to solve problems together requires both of you to understand and communicate with each other.
GDCR11 was a global event: coders all around the world came together to practice writing code without deadlines, legacy code base, ever changing requirements and such, just to form communities, to meet others, and the most important: to learn.
And by learning, I don’t just mean seeing different languages and testing frameworks in action or experimenting with TDD and CleanCode principles in general, there’s way more than those. For example, by pairing with people I’d just met, I saw how hard it can be to work with me sometimes: I noticed I’m just too bull-headed sometimes to accept others people’s ideas. It was also interesting to see how others interpret rules of TDD, how big are the steps they take while writing tests and code.
It was totally worth it to attend (btw. thanks for the sponsors, Mimox and MyCorporation!), I’m sure I will be there at the next one (note that it doesn’t have to be a global event, a day of Coderetreat can be organized at any time, anywhere), and I recommend it for any developers enthusiastic about developing their professions as well!
Update: Oh, there is a Facebook page for Coderetreat@Budapest!