控制反转特定于OO语言吗?

时间:2009-05-04 15:29:49

标签: design-patterns oop inversion-of-control

提出这个问题的另一种方法是:根据你的控制反转是什么?

我问这个问题是因为关于IoC的维基百科文章被非OO解释所劫持。这取自discussion page,来自2007年:

  

我冒昧地完全重写了这个页面,因为之前的内容完全由无意义的“面向对象”的唠叨接管......

我没有看到Inversion of Control如何在OO语言之外有任何意义。在程序语言中放弃控制已经有很多解释(事件编程就是其中之一),纯粹的函数式语言不需要像控制反转这样的概念,因为它们具有更高阶的函数。

此外,在Martin Fowler详细阐述IoC的article中,他专门处理OO示例。

那么,IoC是否只是一个OO概念,它究竟是什么?

对我来说,IoC试图在大多数OO语言强加的限制范围内将函数转换为数据,并尝试将这些函数作为参数传递给其他函数。这不是IoC的唯一部分,但也有一些。

还有工厂设计模式,在传递之前构建和配置对象树。

对我来说,IoC完全是一个OO概念。

你的回答是什么?

4 个答案:

答案 0 :(得分:13)

控制倒置绝对不是OO概念。

IoC存在并且在非OO语言中经常使用。例如,它在C中很常见。 Windows API就是一个很好的例子 - 每当你调用任何通过回调工作的Windows API函数时,你基本上都是以最原始的形式使用IoC。

例如,看一下EnumWindows函数。使用它,将函数指针(EnumWindowsProc)传递给库,并从库代码中运行代码。

将此与维基百科的控制反转定义进行比较:“当库程序调用用户程序时,会发生控制反转。”

完全一样。

但是,当您添加富类型系统和OOP附带的许多其他工具时,IoC确实变得非常强大,灵活且易于使用。这使它更常见,因为它“使用起来更好”,但它确实存在于OOP之前。

答案 1 :(得分:11)

从实施角度看待理论问题。出现的第一个问题应该是究竟是什么控制你反转

然后你会意识到它的一个对象,方法,函数或者诸如此类的东西并没有关系,而是代码所做的事情。

简而言之,当您执行依赖注入时,您将反转对(资源)依赖项的创建和使用的控制。

当您为Windows API函数提供指向回调函数的指针时,您可以控制使用自己的参数调用函数。

所以你看,IoC只是一个理论概念,当然,它可以有不同的实际实现。

答案 2 :(得分:7)

嗯,“控制反转”的概念似乎适用于你可以通过某种方式传递函数指针的地方。基本上,插件概念和具有兼容签名的DLL(例如考虑驱动程序)只不过是IoC的一种形式。

但是,当IoC使用丰富的类型和容器模型时,您基本上会自动进入OO世界。 OOP的概念很好地映射到IoC概念,特别是在支持纯虚拟类(或“接口”,也称为)的多重继承的语言中。

答案 3 :(得分:1)

事实上,IoC的OO实现非常复杂,因为函数通常不是一等公民。

正如Azder所说:IoC的使用有很多原因。我将在这里总结一些来说服:)

迭代

#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 );

线程创建

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

一般事件调度

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

这些示例都不是面向对象的,q.e.d ..