Question

The words invert or control are not used at all to define Inversion of Control in the definitions that I've seen.

Definitions

Wikipedia

inversion of control (IoC) is a programming technique, expressed here in terms of object-oriented programming, in which object coupling is bound at run time by an assembler object and is typically not known at compile time using static analysis. ~http://en.wikipedia.org/wiki/Inversion_of_control

Martin Fowler

Inversion of Control is a common pattern in the Java community that helps wire lightweight containers or assemble components from different projects into a cohesive application. ~ based on http://www.martinfowler.com/articles/injection.html (reworded)


So why is Inversion of Control named Inversion of Control? What control is being inverted and by what? Is there a way to define Inversion of Control using the terminology: invert and control?

Was it helpful?

Solution

Let's say you have some sort of "repository" class, and that repository is responsible for handing data to you from a data source.

The repository could establish a connection to the data source by itself. But what if it allowed you to pass in a connection to the data source through the repository's constructor?

By allowing the caller to provide the connection, you have decoupled the data source connection dependency from the repository class, allowing any data source to work with the repository, not just the one that the repository specifies.

You have inverted control by handing the responsibility of creating the connection from the repository class to the caller.

Martin Fowler suggests using the term "Dependency Injection" to describe this type of Inversion of Control, since Inversion of Control as a concept can be applied more broadly than just injecting dependencies in a constructor method.

OTHER TIPS

I don't think anyone can explain it better than Martin Fowler does, further down the article you linked to.

For this new breed of containers the inversion is about how they lookup a plugin implementation. In my naive example the lister looked up the finder implementation by directly instantiating it. This stops the finder from being a plugin. The approach that these containers use is to ensure that any user of a plugin follows some convention that allows a separate assembler module to inject the implementation into the lister.

As he explains in the paragraphs above that, this is not quite the same as the reason the term "Inversion of Control" originated.

When these containers talk about how they are so useful because they implement "Inversion of Control" I end up very puzzled. Inversion of control is a common characteristic of frameworks, so saying that these lightweight containers are special because they use inversion of control is like saying my car is special because it has wheels.

The question, is what aspect of control are they inverting? When I first ran into inversion of control, it was in the main control of a user interface. Early user interfaces were controlled by the application program. You would have a sequence of commands like "Enter name", "enter address"; your program would drive the prompts and pick up a response to each one. With graphical (or even screen based) UIs the UI framework would contain this main loop and your program instead provided event handlers for the various fields on the screen. The main control of the program was inverted, moved away from you to the framework.

Which is why he goes on to coin the term "Dependency Injection" to cover this specific implementation of Inversion of Control.

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.

To clarify a little: Inversion of Control means anything which inverts the control structure of a program from the classic procedural design.

In days of yore, a key example of this was letting a framework handle communication between a UI and your code, rather than leaving your code to generate the UI directly.

In more recent times (when such frameworks pretty much dominated, so the question was no longer relevant), an example was inverting control over the instantiation of objects.

Fowler, and others, decided that the term Inversion of Control covered too many techniques and we needed a new term for the specific example of instantiation of objects (Dependency Injection) but, by the time that agreement had been made, the phrase "IoC Container" had taken off.

This muddies the water a lot, because an IoC container is a specific kind of Dependency Injection, but Dependency Injection is a specific kind of Inversion of Control. This is why you're getting such confused answers, no matter where you look.

Here's the "regular" control flow programs usually followed:

  • Run commands sequentially
  • You maintain control over the control flow of the program

Inversion of Control "inverts" that control flow, meaning it flips it on its head:

  • Your program doesn't control the flow anymore. Rather than calling commands as you see fit, you wait for someone else to call you.

That last line is the important one. Rather than calling someone else when you feel like it, someone else calls you when they feel like it.

A common example of this is web frameworks such as Rails. You define Controllers, but you don't actually decide when those get called. Rails calls them when it decides there's a need.

This is about who controls instantiation of dependencies.

Traditionally, when a class/method needs to use another class (dependency), it is instantiated by the class/method directly. It controls its dependencies.

With Inversion of Control (IoC), the caller passed in the dependency, hence it (or a higher up caller) instantiates the dependency. The caller controls the dependencies.

The control of where a dependency is instantiated has been inverted - instead of being at the "bottom", where the code that needs it exists, it is instantiated at the "top", where the code that needs it is being called.

Typically higher level code calls (ie, controls) lower level code. Main() calls function(), function() calls libraryFunction().

That can be inverted, so the low level library function at the bottom calls higher level functions.

Why would you do that? Middleware. Sometimes you want to control the top level and the bottom level, but there's a lot of work in the middle you just don't want to do. Take the implementation of quicksort in the C stdlib. You call quicksort at the top level. You hand qsort() a function pointer to your own function that implements a comparator on whatever you feel like. When qsort() is called, it calls this comparator function. qsort() is controlling/calling/driving your high level function.

Here's a simple overview:

  1. Control refers to what the program does next
  2. On the top level, there are typically two things that control the control: the application itself and the user

In the olden days, control was owned by the application first and the user second. If the application needed something from the user, it would stop and ask and then move on to its next task. The user's interaction provided mostly data rather than controlling what the application did next. This is a little foreign to us nowadays since we don't see this type of behavior very often.

If we switch that around and give the user primary control, then we have inverted the control. This means that instead of the user waiting around for the application to give it something to do, the application sits around waiting for user to give it something to do. GUI's are a great example of this and pretty much anything with an event loop has inverted control.

Note that my example is on the top level and that this concept of inversion of control can be abstracted to different layers of control within the application (i.e. dependency injection). This may be why it is so hard to get a straight answer.

Let us try to understand it through the two examples.

Example 1

In earlier days, apps used to generate command prompts to accept user inputs one after other. Today, UI frameworks instantiates various UI elements, loop through various events of those UI elements (like mouse hover, click etc.) and user/main programs provides hooks (for example UI event listeners in Java) for listening to those events. So the main UI element flow "control" is moved from user program to UI framework. In earlier days, it was in user program.

Example 2

Consider class CustomerProcessor below:

class CustomerProcessor
{
    SqlCustRepo custRepo = new SqlCustRepo(); 
    private void processCustomers()
    {
            Customers[] custs = custRepo.getAllCusts();
    }
}

If I want processCustomer() to be independent of any implementation of getAllCusts(), not just the one provided by SqlCustRepo, I will need to get rid of line: SqlCustRepo custRepo = new SqlCustRepo() and replace it with something more generic, capable of accepting varied type of implementation, such that the processCustomers() will simply work for any provided implementation. Above code (instantiating required class SqlCustRepo by main program logic) is a traditional way and it does not achieves this goal of decoupling processCustomers() from implementation of getAllCusts(). In inversion of control, the container instantiates the required implementation class (as specified by, say xml configuration), injects it in the main program logic which gets bound as per hooks specified (say by @Autowired annotation or getBean() method in spring framework).

Lets see how this can be done. Consider below code.

Config.xml

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
    <bean id="custRepo" class="JsonCustRepo" />
</beans>

CustRepo.java

interface ICustRepo 
{ ... }

JsonCustRepo.java

class JsonCustRepo implements CustRepo
{ ... }

App.java

class App
{
    public static void main(String[] args) 
    {
        ApplicationContext context = new ClassPathXmlApplicationContext("Config.xml");
        ICustRepo custRepo = (JsonCustRepo) context.getBean("custRepo");
    }
}

We can also have

class GraphCustRepo implements ICustRepo { ... }   

and

<bean id="custRepo" class="GraphCustRepo">

and we will not need to change App.java.

Above the container (which is the spring framework) has the responsibility to scan xml file, instantiate the bean of specific type and inject it into the user program. User program have no control on which class is instantiated.

PS: IoC is generic concept and is achieved in many ways. Above examples achieves it by dependency injection.

Reference: Martin Fowler's article.

Licensed under: CC-BY-SA with attribution
scroll top