I’ve been interested for a while in the relationship between TDD and good design for a while, and the  SOLID principles of Object Oriented Design in particular. I’ve got this set of 4 “Racing Car” exercises that I originally got from Luca Minudel, that I’ve done in coding dojos with lots of different groups. If you’ve never done them, I do recommend getting your editor out and having a go, at least at the first one. I think you get a much better understanding of the SOLID principles when you both know the theory, and have experienced them in actual code.

I find it interesting that in the starting code for each of the four Katas there are design flaws that make it awkward to write unit tests for the code. You can directly point to violations of one or more of the SOLID principles. In particular for the Dependency Inversion Principle, it seems to me there is a very direct link with testability. If you have a fixed dependency to a concrete class, that is always going to be harder to isolate for a unit test, and the Tyre Pressure exercise shows this quite clearly.

What bothers me about the 4 original exercises is that there are actually 5 SOLID principles, and none of them really has a problem with the Liskov Substitution Principle. So I have designed a new exercise! It’s called “Leaderboard” and I’ve put it in the same git repository as the other four.

I tried it out last week in a coding dojo with my colleagues at Pagero, and it seemed to work pretty well. The idea is that the Liskov principle violation means you can’t propely test the Leaderboard class with test data that only uses the base class “Driver”, you have to add tests using a “SelfDrivingCar”. (Ok, I confess, I’ve taken some liberties with what’s likely in formula 1 racing!) Liskov says that your client code (ie Leaderboard) shouldn’t need to know if it has been given a base class or a subclass, they should be totally substitutable. So again, I’m finding a link between testability and good design.

Currently the exercise is only available in Scala, Python and Java, so I’m very open to pull requests for translations into other programming languages. Do add a comment here or on github if you try my new Kata.

2 Comments

  1. Peter Kofler says:

    Emily, thank you for this new kata. I agree the LSP is somehow often left behind, probably it is difficult to come by (but still quite common in real world).

    Some comments to the kata (Java version): Unlike the katas from Luca, here one has to look at more than the main class Leaderboard. The real problem is in Race. You could put the whole focus into Leaderboard by moving the instance-of check there. This simplifies Race and makes it a simple bean/container, which makes the kata easier to understand on the whole. (It changes the logic, but imho that does not matter.) So maybe if some people find the initial code complex or too difficult to understand, this might help.

    Further the LSP violation does not really prohibit testing, unlike random numbers or singletons. I can easily write a matching assertion using the real name of the self driving car. This does not mean that it feels good to do so, actually I marked the line as “// ugly” when I did the kata. It is just less obvious – again when compared to some of Luca’s exercises. I wonder if it would be possible to make it even more focused, but I do not have any good ideas right now.

    The real LSP violation is the change of contract, Driver’s name is immutable, SelfDrivingCar’s name is not. The fact that the code of the name is put somewhere else does not change that, maybe only hides it. Depending on the view point, having mutable driver names could be a bug, or a feature, although I would expect the company of the self driving car would like to win the world cup with changes of algorithms in between 😉

    After all this is a great kata in the spirit of Luca’s SOLID exercises. Keep up the good work Emily.

  2. Emily Bache says:

    Hi Peter,

    Thanks for the suggestions, you’re right, the code could be simplified further and still demonstrate the LSP problem and testability consequences. I already simplified it considerably compared with my first attempt. I think that’s the beauty of Luca’s original exercises, that there is so little code.

    I agree that the LSP violation doesn’t actually prohibit testing in this case. I suspect that is also the case more generally. It does force you to write more test cases though, since you can’t test it purely with the base class. I’m not sure it’s possible to construct a problem where you can’t test it due to a LSP violation.

    I think pretty much all the Katas I’ve personally designed have been too complex, even if this is the simplest so far. Thanks for the feedback and concrete ideas for simplification!