Tag: TDD
Trying Something New
by George on Jun.26, 2010, under Coding, Uncategorized
This site has been quiet for too long. That’s why I’ve got involved with the #iDevBlogADay initiative. There’s a bunch of great indie developers contributing as part of a regular roster. If you want to follow all of us just subscribe to this feed.
Any good programmer is always looking for new tools and ideas to improve the code they write and to become more productive. For myself, fifteen years after I began coding professionally, this is truer than ever.
So when Noel Llopis started dropping odd comments on Twitter about ‘no classes’, ‘plain old data structures’ and ‘no singletons’ I was intrigued. How did this work? Where did this style come from? Did it lead to simple, effective code? Was it a style that would work for me? Is it a style that will work for you?
If you haven’t already read Noel’s article from yesterday describing his current coding style, then go ahead and read it now.
Take your time, I’ll wait.
It’s definitely an unusual style, and flies in the face of ‘traditional’ wisdom. So what’s life like in a world without objects? Pretty cool, actually. I’ve been experimenting with it for the last couple of weeks, and here are a few observations that might encourage you to give this style a go.
The ‘Rules’
It’s hard to change style so dramatically, so a few rules of thumb are useful to help keep on track. This style is sufficiently different that it takes time to get your head around it. Prepare to spend some time writing (and re-writing) your first code this way.
- No classes.
- Use simple structs to store data / state information, making everything visible.
- Avoid dynamic memory allocation and pointers in general.
- Nothing is global – all data is passed as needed to functions that require it.
- Functions have a single purpose – for a given set of input data, generate an output, avoiding any side effects.
- Use TDD for everything.
TDD Becomes Much Easier
Test Driven Development (TDD) has always appealed to me, but to be honest my history with TDD is a bit like my attempts to build a model railway – plenty of well intentioned starts but no completed projects. Sooner or later I’d always give up on TDD because it just didn’t fit the way I’m used to coding.
But in a world of simple data and functions with a single purpose, TDD comes into it’s own. The tests you write drive the code to be as simple as possible with none of the cruft that typically accumulates in class definitions. And constructing tests is simple – create some simple test data, pass it into a function and check the resulting outputs. All tests follow this simple formula, with not a single pesky mock object in sight.
Lean Code And A Sense Of Progress
The resulting code feels resistant to bloat. Nothing is hidden, and every function has a clear purpose with no unexpected side effects. Time will tell if this pattern persists as the code matures. I’m constantly surprised by the way the code evolves down unexpected avenues.
Every test, every function has a purpose that is clearly defined. This simplicity has a huge appeal. A test and the code that goes with it can be written fairly quickly, and each additional test provides visible progress.
Struct Is The New Interface
I’m used to relying heavily on interfaces or abstract classes in my coding, and the lack of such an option concerned me somewhat. It still does – I miss the option to have a collection of ‘game objects’ and know that I can call Update() on all of them no matter what they are – Crates, Zombies or Flying Quesadillas.
What did surprise me was that rather than accumulating everything into a single class, the data naturally falls into a collection of several parts more in keeping with the idea of components in an OO system (composition over inheritance). For example, when I was writing a leaf particle system the resulting code combined the following bits of data – a mesh, an array of (generic) particles, an array of leaf specific particle data and a free-list for deleting and creating particles from a statically allocated array.
This fragmentation may seem unfortunate, but in fact it’s a strength. The functions that deal with a mesh are applicable to all meshes, not just rendering particles. The free-list struct and functions can be used anywhere that elements in an array need to be frequently created and destroyed. Where in an OO design you carry around an entire object to each method or function call, with this approach you only pass around the ‘part’ of the object that is directly relevant.
Coding Is Fun Again
Ultimately this is the most important point for me. I’m enjoying coding this way. Progress is rapid, and through the use of unit testing, progress is very visible. My free time for game programming is extremely limited, so the ability to write code in small, manageable chunks is a big win. Refactoring can be undertaken with confidence, knowing that the unit tests and the basic structure of the code give some protection against unintended side effects.
This style won’t suit everyone, and it will absolutely terrify the Architecture Astronauts, but if you’re interested then give it a go and let me know how you get on!