It was with some interest I spotted a positive mention of something called Context IoC (a new type of IoC apparently) on Dion Hinchcliffe’s Blog. The while topic really bores me right now as IoC stopped being something fancy a long time ago, and to me it’s now nothing more than “calling a proper constructor”. I investigated further as Dion normally writes very sensibly, does some very nice diagrams and has impeccable taste.
Contextual IoC is outlined in a ServerSide piece by Sony Mathew. It’s not surprising I missed it the first time round as I stopped reading the ServerSide a while back. It turned out I really wasn’t missing much. He starts off on shaky ground:
IOC seems to be at odds with the fundamental paradigm of object encapsulation. The concept of upstream propagation of dependencies is indeed a contradiction to encapsulation. Encapsulation would dictate that a caller should know nothing of its helper objects and how it functions. What the helper objects do and need is their business as long as they adhere to their interface – they can grab what they need directly whether it be looking up EJBs, database connections, queue connections or opening sockets, files etc..
He almost makes a point here, but ends up saying “Objects should interface with things with interfaces”. To those of us who create interfaces to reflect the role a concrete class has in a system, this is nothing new. Quite who this is “at odds with the fundamental paradigm of object encapsulation” I’m not quote sure.
Things then look up a bit:
The benefits of IOC are that objects become highly focused in its functionality, highly reusable, and most of all highly unit testable.
That I agree with. Then we’re off again:
The problem with exposing dependencies via constructors or Java bean properties in general is that it clutters an object and overwhelms the real functional purposes of the constructor and Java bean properties.
I agree with exposing setters purely to provide dependencies – but constructors? At this point it’s clear that Sony and I disagree on what a constructor is – apparently creating an object with the tools it needs to do its job is not what a constructor is for. At this point we’re waiting for Sony’s solution – and the solution is Contextual IoC.
Let’s look at Sony’s example of this:
public class PoolGame {
public interface Context {
public String getApplicationProperty(String key);
public void draw(Point point, Drawable drawable);
public void savePoolGame(String name,
PoolGameState poolGameState);
public PoolGameState findPoolGame(String name);
}
public PoolGame(Context cxt) {
this.context = cxt;
}
...
}
Right, so what’s happened here is that we’ve taken dependencies (in the form of method calls – the PoolGame requires and folded them into an inner interface. Question 1 – how is this different from passing in the roles as separate interfaces? It seems to me with have the need for 3 distinct roles, something along the lines of PoolRepository (for savePoolGame() and findPoolGame()), Display (for draw()) and ApplicationConfig (for getApplicationProperty()). My version of the code would be:
public class PoolGame {
public PoolGame(
PoolRepository rep,
Display display,
ApplicationConfig config) {
...
}
}
So Sony’s code is dependent on having implementations of four methods, my code as a dependency on a implementations of three roles in the system. Lets look at the “benefits” of this approach:
The Context interface removes the clutter of exposing dependencies via constructors or Java bean properties
Does my constructor look any more cluttered than Sony’s inner Context interface? I know my object is going to be easy to create too – how easy is it to create Sony’s? Will it look as simple as constructing my version? So I dispute that benefit. Next:
It provides better clarity by organizing an object’s dependencies into a single personalized interface unique to that class. The PoolGame.Context interface is unique to the PoolGame class.
And that’s a benefit how? It’s a simple matter to see where my roles are used in the system – with contextual IoC you have to look for Context implementations that use things like PoolRepository, which would still need to exist. You’d still need to create things that perform storage and queries of games, things that display the games, or access application properties. But with contextual IoC you also have to create context objects to wrap them up.