A slightly different approach to Context IoC

I read Sam’s post on Contextl IoC, questioning its benefits. I’ve been skirting around this kind of thing for a while. I like the idea of being able to package all the things which a class needs in a box which ‘belongs’ to it.

Say my main class, Gamey, knows how to start new Tetris games.

It needs a game factory which creates games.

The game factory needs to know about user preferences, the gui components to be used to draw the game, the score system, the rules, the timer which drops the shapes, the factory which makes the shapes, etc.

So I need to construct the GameFactory as:

new GameFactory(UserPreference preference, GuiComponentFactory factory, Scorer scorer, RulesEngine rulesEngine, Timer timer).

and ditto for the game it creates.

Except that what I really want is to be able to create different kinds of games, so I can choose to play either Tetris or PacMan, and use a different game factory for each one. They still each need the same stuff – a component factory, a preference, a scorer, a rules engine, a timer etc – so now I have to duplicate that factory constructor for both types of factory; the TetrisGameFactory and the PacmanGameFactory.

Now I want to add multiplayer support, so that each monster killed appears in another person’s game, or each line deleted causes extra blocks to appear elsewhere. Now I need to add MultiplayerSupport to:

  • Two GameFactory constructors
  • Two Game constructors
  • The calls for Game construction
  • probably some abstract stuff in some AbstractGameFactory, and some AbstractGame, etc.

And I don’t even know, in the GameFactory, which bits are related to the Game and which bits are being passed further down, to the Game’s pieces, like the Tetris shapes and the Pacman ghosts, which are also factory-driven but which need to be created by type. Oops, forgot the PiecesFactory. That’s another change, then.

I really like the concept of a Game.Context and a Shape.Context and a Tetris.Context and a Gamey.Context. They can even extend each other or contain each other if required – for instance, the Tetris.Context extends a Game.Context, and contains a ShapeFactory which needs a Shape.Context. Then, when I want to change a dependency, all I need to do is change one context and its construction. I don’t need to pass it through all the layers, abstract and otherwise.

This solves a real problem I’ve been coming across when trying to do behaviour driven design. I don’t want to have to think about the behaviour of my shapes when I’m still thinking about the responsibilities of my games. If I can give the game an empty Game.Context to start with and never worry about how the GameFactory constructs the Game again, then that’s one less piece of code to change every time I decide to add a bit of functionality.

The Game.Context shouldn’t be responsible for using the Game’s tools for it, though. It’s just a little container; nothing else. It should probably just have get methods (ugly, but suggestions welcome; will think on it) for each of the tools it requires.

I’m not even sure that the Game.Context needs to be an interface. It never needs to be mocked – you mock the tools underneath, not the container.

Stacy reckons there has to be another way to prevent the duplication which keeps cropping up in my normal dependency injected code. I also reckon ‘context’ is a poor name; ‘toolbox’ might be better.

This entry was posted in Uncategorized. Bookmark the permalink.

One Response to A slightly different approach to Context IoC

  1. thoth says:

    What you call a Context, we call a Config, with typical accessors like getLog(), getInitProperties(), etc.

    The ease of maintaining a contract of the form:

    public Thing(ThingConfig config) ...


    public Thing(Log log, Properties props, FooFactory factory....

    becomes apparent pretty quickly. Good times.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s