IoC seems to have become the cornerstone concept of many frameworks and object-oriented designs since it was described by Martin Fowler, Robert Martin and others ten years ago. Despite its popularity IoC is misunderstood and overcomplicated all too often.
Look at this code:
print(book.title());
It is very straight forward: we retrieve the title from the book and simply give it to the print()
procedure, or whatever else it might be. We are in charge, the control is in our hands.
In contrast to this, here is the inversion:
print(book);
We give the entire book to the procedure print()
and it calls title()
when it feels like it. That is, we delegate control.
This is pretty much everything you need to know about IoC.
Does it have anything to do with dependency injection containers? Well, of course, we could put the book into a container, inject the entire container into print()
, let it retrieve the book from the container and then call title()
. But that’s not what IoC is really about—it’s merely one of its perverted usage scenarios.
The main point of IoC is exactly the same as I was proposing in my previous posts about naked data and object friends: we must not deal with data, but instead only with object composition. In the given example the design would be even better if we got rid of the print()
procedure altogether and replaced it with an object:
new PrintedBook(book);
That would be pure object composition.
There is not much more to say on this subject; I hope I have cleared it up for you—it is just as simple as that.