Christoph Gockel

Tic Tac Toe Refactorings

09 Jul 2014

In yesterdays weekly iteration meeting with Jim, I got new ideas and views how my TTT implementation could be improved. After Jim explained issues with the existing code, I catched myself often asking myself “Why haven’t I thought of this in the first place? It seems so obvious now it was explained to me.

Some issues were related to my not-yet-very-Ruby-like implementations. I’m starting to consider every method longer than 4 lines not neccesarilly malformed, but at least as a chance to be improved (i.e. shortened).

I remember, in a Peepcode Play by Play episode (now Pluralsight), Ben Orenstein goes as far as considering every Ruby method longer than one line as smelly. Of course, he further explains, no one should take this as the absolute truth or mandatory, but at least as food for thought. He also wrote about it on his blog.

And today I’ve experienced it myself. What before was totally fine code (granted, not very fine Ruby code, but still…), could be refactored to very simple methods containing mostly just one line.

A good example for that is my Board class. The old version of it passed the tests, but wasn’t implemented very ruby-esque.

The refactored version of it is far more concise, and it even got more responsibilities, because the now-deleted Rules class has been merged into Board.

Which brings me to the next topic: feature envy.

My Rules class envied my Board, which was very apparent because nearly every method in Rules either got a board passed to it, or queried it to get information about its state.

What I thought was would be a good application of separation of concerns, turned out to result in two classes that actually belong together.

My intention was to have a Board just as a “bucket” for player moves and a separate thing that examines such a board (e.g. a Rules object). But there’s no point in separating these two things in a context like the Tic Tac Toe game. Because the Board isn’t an ubiquitous usable board for every game one could think of anyway, separating the “interpretation” of a board doesn’t bring any real value to the software. It’s even worse, because the complexity of the overall project was bigger and the feature envy smell was present.

Tomorrow I will work further on the findings. Among others, the I/O parts for a game will be extracted into a separate class and be bested - of course.