fbpx

Introduction

Inversion of control seems to be a tricky topic among developers and every developer declins it in its own way.

Searching on the web it seems that first usage of this term – that is not a pattern, rather a concept or a metodology – is attributable to Michael Mattson, an IT student who wrote a thesis about Frameworks whose title is “Object-Oriented Frameworks A survey of methodological issues” back in 1996.

The major difference between an object-oriented framework and a class library is that the framework calls the application code. Normally the application code calls the class library. This inversion of control is sometimes named the Hollywood principle, “Do not call us, we call You”.

First thing worth of an highlight is the clear difference between a framework and a library. A library is only something you can leverage on to “complete a task”: has a public API at which you ask for something and, sometimes, you receive a result back. A framework is different not because is “larger” or “complex”. A framework is different because is designed to be general purpose about a lot of aspect of an application, not only one. Thinking about this and “inversion of control” is safe to say that, as long as a framework retains the “control” of the flow of your application, it is the “entry point” where the logic is applied. Your application, the custom code, is just “fitted” somehow in it. Think about Symfony framework: each HTTP request is, at first, handled by symfony router that will dispatch it correcly to the right controller where custom code can be connected in order to execute any kind of code. The request-response flow is well defined so is the framework that handle it for you.

The key concept of Inversion Of Control (IoC) is this, nothing more, nothing less.

Going over framework coupling

Couple IoC concept to framework one is at least reductive but, for sure, wrong. I’ll try to explain it below but to start let’s think about a framework for what it is: a (large) bunch of general purpose classes and lines of code. Nothing more, nothing less. So, as long as framework is code, you can apply the IoC principle IN your application code, wheter you choose to use a framework or not. And thinking about this is pretty clear that even libraries can “implement” this concept.

Dependency injection

One of the application of IoC is dependency injection pattern. This term is somehow become a synonymous of IoC but that’s not correct. In this blog article, Martin Fowler says

As a result I think we need a more specific name for this pattern. Inversion of Control is too generic a term, and thus people find it confusing. As a result with a lot of discussion with various IoC advocates we settled on the name Dependency Injection.

Of course I’m not claiming that Martin or Michael are wrong but we need to contextualize those concept; Michael (that is AFAIK the first that used this term, so is not “guilt” about the wrong usage of it) wrote a thesis about Framework so is perfecly legit that he referes to IoC that way. Martin too tries to semplify it in order to get rid of some misconcept about IoC itself. Both were absolutely right. Moreover don’t understimate the fact that 1996 and 2004 (the date of Martin Fowler blog post) are, in term of IT ages, “geological eras” at the time I write this article. If you’re interested in this topic, Martin’s blog post shows his reason  about this simplification.

Talking about “whys”, DI is an implementation of IoC because you choose to give away the control of object instantiation: when and how they’re created is no more a problem that you need to worry about. I would not focus on “how” but on “when” because that’s somehow the essence of IoC: the flow, the control.

Of course you can read more about this concept in Martin blog post: I will not write any more words on DI and why it is “assimilable” to IoC as is very well explain by Martin.

The concept

The basic idea behind IoC is to provide a sort of “plug” in the code where whoever use the code can “plug in” its custom code. The main flow is well known and “plugged” code is there to provide customization. Receive the control from someone else is not the real advantage. Provide an abstract structure, or flow, that follows rules but is “extandable” (not in OO sense) and decoupled is the real advantange (and is derived by this inversion of course). And when it is decoupled you can choose to switch, for instance, between an implementation of your logic, to another. Last but not least, if you can easily switch between implementations, you can easily “fake” those implementations too; as a “side effect” testing is eased a lot. The inversion forces who write the code to be abstract about custom implementations encouraging code decoupling (think how easier is to switch injected service with “A” implementation to service with “Z” implementation; is centralized, is abstract, is testable, is fast!)

So, what?

Wonder how you can understand better IoC and how you can write code that leverages on this concept? Wonder what other implementation than DI can be considered IoC? It is easier than you ever thought.

Event loop/Message Dispatcher/Message Loop

This pattern embody IoC concepts. Look at this snippet from symfony form component. It is reported below with some cuts here and there

Pay attention to this

and

Form component has its known and well structured steps to follow in order to set data from an object to the form and vice versa. There are steps that need to be taken in order to guarantee the correctness of this operation. Then IoC with message dispatcher kicks in: if custom code need to manipulate data, or perform operations, before or after those sets, it can implement a listener or subscriber in order to fulfill the goal. Flow is preserved, logic is preserved and custom logic can be implemented without explicitly extending this class and, more important, avoiding extension to obtain this kind of customization, helps to preserve the logic.

Template Method

Look at the definition of template method that is well explained here. Template Method is another example of how IoC can be implemented. I will not explain what template method is and when is useful as you can find infos in the blogpost linked above.

Let’s consider this

We are implementing user registration in our product. When a user is registered we would like to enable it, possibly send a verification (here comes the IoC, we’ll se how and why) and write data into the database. As you might have noticed, sendVerification function is abstract and is responsability of the concrete UserRegister to implement the logic behind this operation. The abstract nature of this method implicitly make it “not mandatory” as we can provide an empty implementation: it’s not a big deal.

When we provide concrete implementations

we’re inverting the control. What’s the benefit behind this: the concrete class doesn’t need to know or, worst, duplicate the main logic and is free to do the only thing that’s missing in the main flow of our application: notify the user. How easy would be to create another type of notification? Just extend the abstract class and implement it. That’s the main power of IoC. Is worth to note, as a final note, that abstract class main method is final in order to prevent subclasses to alter its behaviour.

Conclusions

IoC allows you to write more robust, decoupled, extensible and testable code. Examples above are only three kind of IoC and more could exists. IoC isn’t DI and it’s not strictly related to frameworks: if you need to write general purpose and easily extensible and decoupled code you should take into account this possibility.

If you have any other examples of IoC or if you don’t agree with something stated in this article, you’re welcome to comment and let us know what you think.

Keep coding!

DonCallisto
DonCallisto
Articoli: 21

Lascia una risposta

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.