Rock Scissors Paper: TDD as if you meant it
I decided to spend a bit of time on Saturday having another go at writing Rock Scissors Paper while following Keith Braithwaite's TDD as if you meant it exercise.
We previously did this exercise at a coding dojo but I wanted to see what happens when you code for a longer period of time with this exercise since we typically only code for maybe a couple of hours at a dojo.
I decided to also checkin the code I was writing into Git after every single change I made – an idea I originally learnt from Dan North, and the code is all on github.
What did I learn?
- I was coding for maybe 4 or 5 hours and checked in about 120 times which is far more frequently than I would do normally although perhaps it shouldn't be.
I thought it would be quite distracting to have to check in that often but the checkin messages ended up becoming a stream of consciousness of what I was thinking which proved quite useful on a few occasions when I got side tracked a bit and retraced my steps in the history to find out what I was supposed to be doing – Git was pretty much acting as my sounding board since I didn't have a pair to work with on this exercise.
I'd definitely try this out again and as I've mentioned a few times I want to try it out in a coding dojo some time.
- While trying to remove some duplication that had worked its way into the code I realised that the template method would be the easiest way to remove that duplication and as I mentioned in an earlier post, having functions/actions in C# makes the implementation of this pattern a bit simpler:
public abstract class ThrowBase : IThrow { private readonly Func<IThrow, bool> beatenBy; protected ThrowBase(Func<IThrow, bool> beatenBy) { this.beatenBy = beatenBy; } .... public bool Beats(IThrow aThrow) { return IsDifferentThrowTo(aThrow) && !beatenBy(aThrow); } } }
public class Scissors : ThrowBase { public Scissors() : base(weapon => weapon.BeatsScissors()) { } ... }
If we didn't have functions then we'd need a method on 'ThrowBase' which we would need to implement in each of its sub classes.
As it is we can just pass a function into the constructor which does the same job.
- Another thing I found quite interesting about this exercise was that I was seeing more easily where methods didn't seem to belong on an existing object and I ended up creating a new object which described the interaction – chatting about the code with Liz she pointed out that I was probably creating domain events which we had discussed a few days earlier in book club.
Once I started thinking about this interactions as 'domain events' the naming of them seemed to be much more obvious – for example after this conversation with Liz I realised that the interaction between two 'Throws' would be a 'ThrowDown' and that there would probably be a 'ThrowDownAdjudicator' to decide the outcome of a 'ThrowDown'.
- I found it quite difficult to follow the rules of the exercise when I realised that I wanted to return a 'ThrowDownResult' which would indicate whether there was a winner for a 'ThrowDown' and if so who it was. I couldn't see a way to write all of this code in the test since I had already created the class previously so I ended up writing this code straight onto the class.
I think I probably extracted to a class too early on some occasions instead of waiting for a more complete version of a method to be written before moving it.
Next time I think I'd wait until I'd completed all the examples /tests I want to write around a particular method before moving it onto a class.
[...] Rock Scissors Paper: TDD as if you meant it at Mark Needham http://www.markhneedham.com/blog/2009/08/24/rock-scissors-paper-tdd-as-if-you-meant-it – view page – cached Thoughts on Software Development — From the page [...]
Twitter Trackbacks for Rock Scissors Paper: TDD as if you meant it at Mark Needham [markhneedham.com] on Topsy.com
26 Aug 09 at 12:43 am
Thank you for the very detailed git history, I'll definately try that out! I read it through to understand how you made stateful objects come to life. Having tried the exercise on the tic tac toe problem for a little longer than a dojo I sure ended up with little and rather clean code. However in trying to follow the rules I found it difficult to have domain concepts emerge and my code ended up not even remotely object oriented with several missing concepts like, a player and fields taken by a player. And perhaps a field object ( http://github.com/martinsson/cara-dojos/blob/master/ticTacToe/src/main/java/ticTacToe/Game.java ). I think this is mainly because I didn't understand how (following Keith's rules) objects with state come to life.
In your example you quickly remove parameters in functions by moving them to the constructor. For instance in your step "Introduce battle class" : "969fe92f4ec2294c095ad8111cc442f87d25afa0″ and the following commit what you actually did was extract BattleHasWinner(rock, rock) to the all new Battle class then moved the two arguments to the constructor? Any thoughts on that? Did it work you nicely or would you do it differently a second time? Would you do it differently if you were programming in a more functional language ( I'm thinking of your discussion with Keith Braithwite http://gojko.net/2009/02/27/thought-provoking-tdd-exercise-at-the-software-craftsmanship-conference)
Johan Martinsson
17 Mar 10 at 11:38 pm
[...] It actually makes development more fun and reminds me of a kata I did while checking in almost every minute last year. [...]
Mercurial: Early thoughts at Mark Needham
10 Apr 10 at 11:44 am