Daniel Irvine on building software
Wrong way round (part 1)
8 June 2014
Recently I’ve been exercising my test-driven development skills via a game of tic-tac-toe. I developed the game one requirement at a time. First, I created a playable API with two human players, then I created both human and computer players, followed by a console version, and finally a GUI version. Each stage was covered by tests encapsulating the requirements.
In amongst all of this awesome TDDness, something surprising happened: I layered my application the wrong way round.
Let’s take a look at how that operates.
The game starts via the
Game class, which controls both the
Board class, which holds the game state, and the
Display class, which is the view. Looking at the
play_turn method in
def play_turn @board.play_turn @display.update_board @display.show_result if @board.game_over? end
The problem with this approach is that any view class must at some point call back into the controller as a result of user events, resulting in a cyclic dependency. This is the
Game callback shown in the diagram. For example, when the user clicks on the screen a mouse click event should be parsed and a ‘play square’ event forwarded to the
That dependency and callback mechanism is overly complex, and that’s the symptom of the “wrong way round” pattern: the code becomes complicated.
Thankfully since all my game logic was covered by tests, inverting this dependency was not exactly hard. It just required some rejigging of the
In part 2 I’ll discuss how I got myself into this predicament and why it’s a great example of why layering makes sense.