Archive for the ‘inversion of control’ Category

Dependency Injection explained in simple terms

Sunday, January 4th, 2009

Martin Fowler wrote a long article about “Inversion of Control Containers and the Dependency Injection pattern“. I recall struggling to read this article back in late 2005 or early 2006. It was really mind numbing at the time. For some reason, folks writing for the Java community feel the need to surround their ideas with a fair amount of ceremony. Also, the folks attracted to Java seem to be folks who are attracted to abstractness for its own sake. Fowler is a great writer and a genius of a programmer. Nevertheless, sometimes it is nice to say things plainly and simply. (Fowler is writing for a tough crowd – experienced Java programmers who can think of a counter-argument to all his arguments, and even counter-counter-counter arguments to all his counter-counter arguments. So his writing must contain a number of qualifiers that add to the complexity.)

I just reread the article and, since I’ve had years to grow used to its ideas, I found it easy to read. Allow me to summarize it here, as quickly and simply as possible, using PHP for what examples I give.

The problem to be solved is dependency. If you have an object that is dependent on another object, then your code is more brittle than it needs to be. A direct call from one object to another is an example of tight coupling. If that dependency could be made less direct, then your code would be more loosely coupled. When imagining the set of classes that will make up your software, your design goal should be “small pieces, loosely joined.”

I’ll use an example similar to the one that Martin Fowler uses.

Imagine you’d like to build some software that looks up all the movies that are made by a particular director. You might have a class that looks like this:

class MovieLister {

function moviesDirectedBy($nameOfDirector) {

$finder = new FindMoviesInCommaSeparatedList();

$arrayOfMovies = $finder->findAllMoviesMadeByThisDirector($nameOfDirector);

return $arrayOfMovies;

}
}

So this method returns an array with the list of movies it just found. If you are using this on a web site, for instance, you could now loop through the array and wrap it in some HTML and, viola, you’ve a nice little service that is listing all the movies made by some director.

But this line of code is bad:

$finder = new FindMoviesInCommaSeparatedList();

It is bad because you are using FinderMoviesInCommaSeparatedList directly, and this is a case of tight coupling. And yes, the name is clearly awful, but that is deliberate. Things would still be just as bad if you changed the name:

$finder = new FindMovies();

If FindMovies still looks up its data in a comma separated list, you are still tightly coupled to a particular way of looking up data. What if, in the future, you want to look up movies in a database?

Let’s imagine that you run a web design shop, and two new customers walk in. They hire you to build two different web sites. They both want to use this movie listing software you’ve developed, but one wants to store data in an XML file, and another wants to store data in a MySql database. How do you adapt the software to those different circumstances? You could edit the code for each customer, but then you’d essentially have two separate software programs, rather than one. Assuming you are called upon to maintain this software, and debug it, you would be facing twice the costs. Wouldn’t it be better if you could stick with one code base, and have a configuration file control those things that need to be different on the different sites?

In a real life application (let’s say for a website) you’ll often have multiple objects in use in a class:

class MovieLister {

private $finder;
private $html;
private $user;

function __construct() {

$this->finder = new FindMovies();

$this->html = new HtmlMaker();

$this->user = new UserManager();

}

function moviesDirectedBy($nameOfDirector) {

if($this->user->isLoggedIn()) {

$arrayOfMovies = $this->finder->findAllMoviesMadeByThisDirector($nameOfDirector);

return $arrayOfMovies;
}
}
}

This is some brittle code. MovieLister now depends on 3 other objects. If you later decide that MovieLister should use replacements for FindMovies or HtmlMaker or UserManager, you need to come here to this class and change the way the code is written. Again, wouldn’t it be better if you could make such changes from the configuration file?

That’s the basic idea of both the “dependency injection” pattern and the “service locator” pattern: the decision about what class you are using gets moved to a configuration file.

Imagine we have an object that can fetch other objects based on settings in a configuration file. We could re-write the constructor like this:

function __construct() {

$dm = new DependencyManager();

$this->finder = $dm->fetch(”FindMovies”);

$this->html = $dm->fetch(”HtmlMaker”);

$this->user = $dm->fetch(”UserManager”);

}

This is more flexible. Imagine that DependencyManager looks in some kind of configuration file (perhaps a big XML file) and finds out that, on this particular website, the call to “FindMovies” should really get FindMoviesMySql, which is a class that looks up the movies in a MySql database. On another website, using the same code but a different configuration, the same call to “FindMovies” fetches an instance of FindMoviesInCommaSeparatedList.

Your code is now more loosely coupled. You can make changes from the configuration file, so you no longer need to come here and directly edit your code, even when you want to make changes to the objects that are in use.

The only problem with the above constructor is that we are still directly dependent on DependencyManager. This could be fixed like so:

function __construct($dm) {

$this->finder = $dm->fetch(”FindMovies”);

$this->html = $dm->fetch(”HtmlMaker”);

$this->user = $dm->fetch(”UserManager”);

}

Now the DependencyManager can be invoked at some high level in your code, and perhaps the place where it is created could also be dependent on some setting in configuration. If you do that, you’ve achieved some wonderfully loose code. Your software is now insulated against a wide variety of changes that it might face in the future.

For the record, “inversion of control” is a fancy term, and it can apply to a lot of things, but when it comes to the “dependency injection” pattern mostly it just means that decisions are being moved from your code to some code that is outside of the current software. That is, normally your script will cause something to happen, and then another thing, and then another thing, but with inversion of control, some outside software will take charge for awhile and make some important decisions.

In his article, Martin Fowler talks about two patterns of managing dependency. He calls these two patterns “dependency injection” and “service locator”. The DependencyManager object that I’m showing in the code above is an example of the “service locator” pattern. This is an object that looks up other objects (other “services”) based on settings in the configuration file. The only possible problem with the service locator pattern is that you still have this object in your code, and you still have its interface there, so changes to its interface could harm your software, so clearly you’ve got a kind of dependence there. Most of the time, this won’t be a serious problem – it’s just the interface you’re dealing with. You can change to a different service locator, so long as it maintains the same interface.

With the dependency injection pattern you assume that you have some high level code, outside of your main code, that initiates your objects and which simply injects the objects that your code is dependent upon. There are different ways to do this but the main way is to use a constructor. So if you were using dependency injection, the above code might look like this:

function __construct($finder, $html, $user) {

$this->finder = $finder;

$this->html = $html;

$this->user = $user;

}

So in this example, all the complicated questions of managing dependencies is removed from your main code and placed in some high level code that works from the configuration and takes care of the dependencies for all of your objects. Your main code ends up looking quite simple, as you can see above.

Which is better, the dependency injection pattern, or the service locator pattern? That depends on context. Martin Fowler has this to say:

Inversion of control is a common feature of frameworks, but it’s something that comes at a price. It tends to be hard to understand and leads to problems when you are trying to debug. So on the whole I prefer to avoid it unless I need it. This isn’t to say it’s a bad thing, just that I think it needs to justify itself over the more straightforward alternative.

…A lot of this depends on the nature of the user of the service. If you are building an application with various classes that use a service, then a dependency from the application classes to the locator isn’t a big deal. In my example of giving a Movie Lister to my friends, then using a service locator works quite well. All they need to do is to configure the locator to hook in the right service implementations, either through some configuration code or through a configuration file. In this kind of scenario I don’t see the injector’s inversion as providing anything compelling.

The difference comes if the lister is a component that I’m providing to an application that other people are writing. In this case I don’t know much about the APIs of the service locators that my customers are going to use. Each customer might have their own incompatible service locators. I can get around some of this by using the segregated interface. Each customer can write an adapter that matches my interface to their locator, but in any case I still need to see the first locator to lookup my specific interface. And once the adapter appears then the simplicity of the direct connection to a locator is beginning to slip.

…So the primary issue is for people who are writing code that expects to be used in applications outside of the control of the writer. In these cases even a minimal assumption about a Service Locator is a problem.

I have a personal PHP framework that’s been in development since 2002. For my personal style of coding, getting the right dependency manager in place was the single most important design decision I ever made. Through trial and error, over the course of two years, I stumbled into my current design. Without even knowing the name of the pattern, I developed a service locator. As Fowler points out, a service locator is the ideal choice for managing dependencies in situations where the author has full control over the relationship between the base code and the client code. When you, as the author, know where your base code (providing services) will live, and where your client code (dependent on those services) will live, then a service locator makes sense.

That was back in 2004, before I had even read Fowler’s article – though having struggled with the issue of dependency, I was hungry for information on the subject (though, as I said above, I found the article overly abstract the first time I read it).

In the end, the dependency manager I put in place allows so much flexibility that I haven’t needed to change it in the last 4 years. It allows my code to evolve with each new project I take on. Whenever I need to replace a class, I simply do so, and the rest of the code is insulated from that change – no surprising bugs crop up.

On a different subject, I’ve already written of a bitter experience I’ve had trying to manage a Flash project. I am curious how dependency injection would be handled in ActionScript 3, and how that would get worked into a Flash project. Maybe I don’t understand enough about Flash/Flex, but the setup of the average Flash project seems resistant to a lot of the best ideas in OOP programming.

(Speaking of Martin Fowler, I just noticed someone has created a PHP version of PicoContainer, for doing dependency injection in PHP the way Fowler suggested.)