控制反转是仅限于面向对象语言吗?

9
另一个询问这个问题的方式是:根据您的理解,什么是控制反转(Inversion of Control)?我之所以问这个问题是因为维基百科关于IoC的文章被非面向对象的解释劫持了。这是来自讨论页面并且是2007年的内容:

我冒昧地完全重写了这个页面,因为先前的内容完全被无意义的“面向对象”废话占领了……

我看不出控制反转在面向过程语言之外有任何意义。已经有很多解释放弃在过程式语言中的控制(事件编程就是其中之一),而纯函数式语言不需要像控制反转这样的概念,因为它们具有高阶函数。
此外,在文章中,Martin Fowler详细阐述了IoC,他只处理面向对象的例子。
那么,IoC是专属于面向对象的概念吗?它到底是什么?
对我来说,控制反转(IoC)试图将函数转化为数据,但受到大多数面向对象语言的限制,并尝试将这些函数作为数据作为参数传递给其他函数。这不是IoC的唯一部分,但其中有一些。
还有工厂设计模式,在传递之前构建和配置对象树。
对我来说,IoC是一个纯粹的面向对象概念。
你的答案是什么?
4个回答

13

控制反转(IoC)绝对不是面向对象(OO)的概念。

IoC 存在并且经常用于非 OO 语言中。例如,在 C 中非常常见。一个典型的例子是 Windows API - 任何时候当您调用任何 Windows API 函数并通过回调函数进行工作时,您基本上是在使用 IoC 的最原始形式。

例如,看一下EnumWindows函数。使用此函数,您将一个函数指针(EnumWindowsProc)传递给库,然后您的代码将从库代码中运行。

将其与维基百科中的控制反转定义进行比较:"当库过程调用用户过程时,就发生控制反转。"

这正是相同的。

然而,当您添加丰富的类型系统和许多其他 OOP 工具时,IoC 真正变得强大、灵活和易于使用。这使它更加普遍,因为它更加“友好”。


完全同意使用丰富的类型系统更容易。如果将函数作为一等公民,它甚至会变得更加容易。 - xtofl

11

你从实现的角度看待理论问题。最先出现的问题应该是: 究竟要反转控制什么 ?

接着你会意识到,无论是传递对象、方法、函数还是其他什么都不重要,重要的是代码实际上做了什么。

总之,当你进行依赖注入时,你反转了依赖(资源)的创建和使用的控制权 。

当你向Windows API函数提供一个回调函数的指针时,你将控制权交给它们,让它们使用自己的参数来调用你的函数。

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


7

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

然而,当在富类型和容器模型中使用IoC时,您将自动进入OO世界。而且OOP的概念非常适用于IoC概念,特别是在支持多重继承的语言中,其中包括纯虚类(或称为“接口”)。


1

事实上,IoC 的面向对象实现非常精细,因为函数往往不是一等公民。

正如 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.。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接