Dependency Injection: Coke with Lime

I have in the past expressed skepticism regarding the utility of Spring’s XML-based dependency injection configuration files. A bit ago, in one of these conversations, I was pointed to Martin Fowler’s article on dependency injection. I found it hilarious.

One of the interesting aspects of the academic side of computer science is the creation if new terms for old ideas. Take a well known concept, add a twist of lime, invent a new term, throw in a little obfuscation, and presto – an instant publishable paper (as long as you’re not submitting to a top-tier journal). It’s publishable because it’s very hard to classify between these junk papers and complicated but genuinely new concepts. (so hard in fact many journals don’t even try – even nonsensical papers can occasionally sneak through) And since people are judged on how many papers they produce, this problem has become an epidemic. The signal to noise ratio is currently mind-bogglingly low.

Dependency Injection I’m now certain is the corporate equivalent of this academic phenomenon. While people many not have as much incentive without the threat of not getting tenure due to too few papers published, the fame of being the guy who invented The Next Big Thing(tm) is non-trivial. And even if you don’t invent it yourself, being an early champaign of The Next Big Thing(tm) distinguishes yourself from your peers, helps you land new contracts, etc. In a myriad of career enhancing ways it’s still a viable incentive.

Not to say it’s a con-job mind you. Buzz-words are everywhere in this business. It’s exciting to be on the cutting edge, and it’s hard to separate out the true leading fronts from the fake ones. It’s real easy to get swept up in the excitement. (I’ve been guilty of it myself on more than one occasion) But that doesn’t change the basic question.

So… Dependency Injection: A new idea or Coke with Lime?

Let’s start with Martin’s own sample code.

class MovieLister...
    private MovieFinder finder;
    public MovieLister() {
        finder = new ColonDelimitedMovieFinder("movies1.txt");
    }
    public Movie[] moviesDirectedBy(String arg) {
        List allMovies = finder.findAll();
        for (Iterator it = allMovies.iterator(); it.hasNext();) {
            Movie movie = (Movie) it.next();
            if (!movie.getDirector().equals(arg)) it.remove();
        }
        return (Movie[]) allMovies.toArray(new Movie[allMovies.size()]);
    }

The method moviesDirectedBy uses an interface:

public interface MovieFinder {
    List findAll();
}

Look at the MovieListener constructor. Martin argues that it’s a bad implementation because it ties the MovieListener class to a specific implementation of a MovieFinder. And he’s absolutely right. It’s pointless to have a MovieFinder interface if your code can only ever use one instance of it.

But this is not a new concept. This is the very basis of object-oriented programming. He may as well have called Dependency Injection “Non-Retarded Programming”. A non-retard implementation would probably contain this:

    public MovieLister(MovieFinder finder) {
        this.finder = finder;
    }

Which, low and behold, is exactly what he recommends. His example is nothing but a straw-man argument.

So my question to you is this: When did having a constructor that takes an argument become a new idea worthy of a new term? I wrote Java programs in 1996 that did this. C++ did it long before that. I mean good god, this idea is as old as object-oriented programming itself.

Now if you’re using the Spring framework, you might write some controlling XML not unlike the following:

<bean id="ColonDelimitedMovieFinder" class="org.kered.ColonDelimitedMovieFinder">
    <constructor-arg index="0" ref="movies1.txt"/>
</bean>
<bean id="MovieLister" class="org.kered.MovieLister">
    <constructor-arg index="0" ref="ColonDelimitedMovieFinder"/>
</bean>

And then the Spring controller would parse this XML, generate your objects, and offer some lookup service to some other code that uses MovieListener. But I ask you this: Why do you need a framework for that? How is this XML any less complicated than actual Java code that does the same thing? For example:


public class MyController {
  private static MovieFinder finder = new ColonDelimitedMovieFinder("movies1.txt");
  private static MovieListener listener = new MovieListener(finder);
  public static getMovieListener() { return listener; }
}

Presto – no framework needed! Plus, you’ve not given up compile-time validity checking of your code. (I love the “rename class” feature of Eclipse – too bad it breaks hard when all your inter-class ties are defined in XML configuration files. Back to using grep on every rename…)

Now, one might argue that the XML configuration gives you run-time flexibility in your architecture. That it allows non-programmers to configure your application in any way they please. But this is a fallacy. These XML configuration files *are* quasi-programming languages (interpreted ones at that). All you’re saving is the compile. You still have to be a programmer to modify them. It is no simpler than modifying the Java source code directly (or the bash/bat script that launches it). You’re simplifying nothing – only shifting the location of the complexity.

Ok Derek, yes, I can’t have my users editing the spring application context files themselves. But I still need to deploy multiple configurations of my architecture that vary significantly. How do I do that when it’s statically compiled?

Simple. Create multiple “controller” classes. (in a 1-to-1 parallel to whatever XML you would have to write anyway) Switch between them with runtime parameters, or a one-line configuration option. Again, Programming 101. And as a bonus, you get to fix the possible number of deployable configurations to a number that’s economically testable, and you prevent the setup of nonsensical configurations.

But Derek, in your example, “movies1.txt” is hard-coded into your program.

Yes, but “movies1.txt” is hard-coded into *both* examples. No application is going to instruct the user to modify that blob of XML either. Both systems would need an additional config file or gui somewhere to expose that option to the user.

To recap: I’m not saying dependency injection is crap. In fact I’ve apparently been programming it for over a decade. I’m just saying it’s a vacant term that offers nothing new to the field of computer science. And I’m saying that Spring’s XML configuration for dependency injection offers you virtually nothing in terms of ease of configuration (except for it being run-time interpreted, which you can get in a variety of simpler ways), and destroys one of Java’s greatest assets: strong compile time validity testing. (And if you don’t care about that, why are you using Java? Go learn Python!)

Update: Check out http://code.google.com/p/unsprung/.

One Response to “Dependency Injection: Coke with Lime”

  1. TK Says:

    I couldn’t agree more.
    Credit is given to Spring for creating a ’standard’ way of configuring objects from XML rather than format X invented at the whim of a programmer. Credit is then immediately taken away for making an army of developers incapable of writing other forms of configuration. (No one would want to change configuration at runtime right?)

    XML is less maintainable than actual code as writing/debugging the XML involves understanding the framework that interprets the XML…

    The Unsprung is awesome. I’ll be filing that away for later use.

Leave a Reply


<Kered.org>   © Copyright 2000-2005 by Derek Anderson
Get Firefox