I know it’s not trendy to re-hash old java programming discussions – I should be discussing some new amazing functional language, however I’m in a grumpy mood. I have a beef with what appears to be the dominant trend of using setter-based dependency injection. I’m an old-skool dependency inject-er – I started with picocontainer when Spring was unheard of (well at least by me). What I particularly like was the way it changed the way I designed my java code. (For the spring-kiddies, PicoContainer *only* supported constructor injection)
A common complaint I hear about constructor injection is “I don’t like having so many constructor arguments”. Yup this crossed my mind when I first came across it too – then it dawned on me: perhaps having too many dependencies injected into a class is a code smell? How many other classes should this class be collaborating with? Am I missing an abstraction in my model? Many times I’ve looked at a class and simply by looking at it’s constructor signature I’ve had a nagging doubt about it’s hygiene.
A big reason I prefer constructor injection is that I can ensure that when an object is constructed is ready to do it’s job. I do not have to concern myself with whether the class has been ‘wired’ correctly in configuration and that all dependencies have been met. If I introduce a new dependency, I can find all places in the code (and pretty quickly in configuration) where I’ve caused a breakage.
However it’s now 2009 and I’m still (occasionally) writing java, but pretty regularly I’m in a team that has settled on setter injection as a standard. It’s the default option in the Rod Johnson scriptures I guess. I also believe in most cases it’s better to be consistent than argue what some see as a fine point, so again I fall into line and am forced to use setter injection. But I do want to bitch about it.
How about this test setup code:
WidgetGetter widgetGetter = new WidgetGetter(); widgetGetter.setHttpClient(new HttpClient()); WeeResourceFactory resourceFactory = new WeeResourceFactory(); resourceFactory.setWidgetGetter(widgetGetter); resourceFactory.setSomeParameter("the quick brown fox"); FooRepository repo = new FooRepository(); repo.setBarFactory(new BarFactory()); repo.setResourceFactory(resourceFactory);
WidgetGetter widgetGetter = new WidgetGetter(new HttpClient()); WeeResourceFactory resourceFactory = new WeeResourceFactory(widgetGetter, "the quick brown fox"); FooRepository repo = new FooRepository(resourceFactory, new BarFactory());
I’m also into configuration in code rather than in XML, but I worry I’ll get burned at the stake if I bring THAT up again.