提出这个问题的另一种方法是:根据你的控制反转是什么?
我问这个问题是因为关于IoC的维基百科文章被非OO解释所劫持。这取自discussion page,来自2007年:
我冒昧地完全重写了这个页面,因为之前的内容完全由无意义的“面向对象”的唠叨接管......
我没有看到Inversion of Control如何在OO语言之外有任何意义。在程序语言中放弃控制已经有很多解释(事件编程就是其中之一),纯粹的函数式语言不需要像控制反转这样的概念,因为它们具有更高阶的函数。
此外,在Martin Fowler详细阐述IoC的article中,他专门处理OO示例。
那么,IoC是否只是一个OO概念,它究竟是什么?
对我来说,IoC试图在大多数OO语言强加的限制范围内将函数转换为数据,并尝试将这些函数作为参数传递给其他函数。这不是IoC的唯一部分,但也有一些。
还有工厂设计模式,在传递之前构建和配置对象树。
对我来说,IoC完全是一个OO概念。
你的回答是什么?
答案 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 ..