views:

373

answers:

4

Another way to ask this question is: what is Inversion of Control according to you?

I ask this question because the Wikipedia article on IoC has been hijacked by a non-OO explanation. This is taken from the discussion page and is from 2007:

I took the liberty to completely rewrite the page, as the previous content was completely taken over by meaningless "object oriented" babble ...

I don't see how Inversion of Control makes any sense outside of OO language. There are already many explanations for giving up control in procedural languages (event programming is one) and purely functional languages don't need a concept like Inversion of Control since they have higher-order functions.

Also, in the article where Martin Fowler elaborates on IoC he exclusively handles OO examples.

So, is IoC exclusively an OO concept, and what is it exactly?

To me, IoC tries to turn functions into data within the limitations that most OO languages impose, and tries to pass those functions-as-data as arguments to other functions. That's not the only part of IoC, but there's some of that.

There's also the factory design pattern, where trees of objects are being constructed and configured before being passed on.

To me, IoC is exclusively an OO concept.

What's your answer?

+5  A: 

Well, the concept of "inversion of control" seems applicable everywhere you have some way to pass function pointers around. Basically, plug-in concepts and DLLs with compatible signatures (think of drivers for instance) are nothing but a form of IoC.

However, when using IoC with a rich type and container model, you'll basically be in the OO world automatically. And the concepts of OOP map very well to IoC concepts, especially in languages which support multiple inheritance with pure virtual classes (or "interfaces", as those are also called).

Lucero
+9  A: 

Inversion of control is most definitely not an OO concept.

IoC exists and is used quite frequently in non-OO languages. It is very common in C, for example. A prime example of this is the Windows API - any time you call any Windows API functions which work via callbacks, you're basically using IoC in it's most primitive form.

For example, take a look at the EnumWindows function. Using this, you pass a function pointer (EnumWindowsProc) to a library, and your code is run from within the library code.

Compare this to the definition of Inversion of Control from Wikipedia: "Inversion of control occurs when a library procedure calls user procedure(s)."

It's exactly the same.

However, IoC really becomes very powerful, flexible, and easy to use when you add a rich type system and many of the other tools that come with OOP. This makes it more common, since it's "nicer" to work with, but it did exist prior to OOP.

Reed Copsey
Totally agree with that it's easier to use with a rich type system. It becomes _even_ easier with functions as first-class citizens.
xtofl
+3  A: 

You look at the theoretical problem from a implementational viewpoint. The first question that arises should be exactly what Control do you Invert ?

Then you will realize that it doesn't matter wether its an object, method, function or whatnot that is passed around, but what actually the code does.

In short, when you do Dependency Injection, you invert the control of the creation and usage of dependencies (of resources).

When you give a Windows API function a pointer to a callback function, you give them the control of calling your function with their own parameters.

So you see, IoC is just a theoretical concept, and ofcourse, there can be different practical implementations of it.

Azder
A: 

In fact, the OO implementation of IoC is quite elaborate, because functions aren't often first class citizens.

As Azder mentioned: IoC is used for a lot of reasons. I'll summarize some here to convince :)

Iteration

#ruby
{1,2,3}.each{ |i| puts i }

#haskell
map [1,2,3] ( \i -> write i )

//the stl algorithms
int printint( int i ){ return printf( "%d", i ); }
std::foreach( onetwothree.begin(), onetwothree.end(), &printi );

Thread creation

CreateThread( NULL, 0, &myFunction, NULL, 0, NULL );

General event dispatching

//javascript
document.getElementById( "mybutton" )
            .addEventListener( 
                 function(e){ alert("buttonPressed") } );

None of these examples are Object Oriented, q.e.d..

xtofl