当第一次遇到控制反转(IoC)时,它可能非常令人困惑。
这是怎么一回事?它解决了哪个问题?什么时候使用合适,什么时候不合适?
当第一次遇到控制反转(IoC)时,它可能非常令人困惑。
这是怎么一回事?它解决了哪个问题?什么时候使用合适,什么时候不合适?
当前回答
例如,任务#1是创建对象。没有IOC概念,任务#1应该由程序员完成。但有了IOC概念后,任务#1将由容器完成。
简而言之,控件从编程器转换为容器。因此,它被称为控制反转。
我在这里找到了一个很好的例子。
其他回答
控制反转是一个通用原则,而依赖注入将这一原则实现为对象图构造的设计模式(即配置控制对象如何相互引用,而不是对象本身控制如何获取对另一个对象的引用)。
将控制反转视为一种设计模式,我们需要看看我们正在反转什么。依赖注入反转了对构建对象图的控制。如果用外行的术语来说,控制反转意味着程序中控制流的改变。例如,在传统的独立应用程序中,我们有一个主要的方法,从那里控制权被传递给其他第三方库(在这种情况下,我们使用了第三方的库的功能),但通过控制反转,控制权从第三方程序库代码转移到我们的代码,因为我们正在使用第三方代码库的服务。但在程序中还有其他方面需要反转,例如调用方法和线程来执行代码。
对于那些对控制反转感兴趣的人来说,已经发表了一篇论文,概述了控制反转作为一种设计模式的更完整的图景(OfficeFloor:使用办公模式来改进软件设计http://doi.acm.org/10.1145/2739011.2739013免费下载http://www.officefloor.net/about.html).
确定的关系如下:
控制反转(用于方法)=依赖(状态)注入+连续注入+线程注入
可用控制反转的上述关系汇总http://dzone.com/articles/inversion-of-coupling-control
假设你是一个物体。然后你去餐馆:
没有IoC:你要求“苹果”,当你要求更多时,你总是得到苹果。
与IoC:你可以要求“水果”。每次上桌你都可以得到不同的水果。例如,苹果、橙子或西瓜。
所以,很明显,当你喜欢品种时,IoC是首选。
在使用“控制反转”之前,你应该充分了解它的优点和缺点,如果你这样做,你应该知道为什么要使用它。
赞成的意见:
您的代码被解耦,因此您可以轻松地将接口的实现与其他实现交换它是针对接口而非实现进行编码的强大动力为代码编写单元测试是非常容易的,因为它只依赖于它在构造函数/setter中接受的对象,并且可以很容易地用正确的对象单独初始化它们。
欺骗:
IoC不仅会反转程序中的控制流,还会使其变得相当模糊。这意味着你不能再只读取代码并从一个地方跳到另一个地方,因为代码中通常存在的连接不再存在。相反,它在XML配置文件或注释中以及IoC容器的代码中解释这些元数据。出现了一类新的错误,即您的XML配置或注释错误,您可以花费大量时间来找出IoC容器在特定条件下向其中一个对象注入空引用的原因。
就我个人而言,我看到了IoC的优点,我非常喜欢它们,但我倾向于尽可能避免使用IoC,因为它将您的软件变成一个类的集合,这些类不再构成“真正的”程序,而只是需要通过XML配置或注释元数据组合在一起的东西,如果没有IoC,它就会崩溃。
假设我们在酒店开会。
我们邀请了很多人,所以我们漏掉了很多壶水和很多塑料杯。
当有人想喝水时,他/她将杯子装满,喝水,然后将杯子扔在地板上。
大约一个小时后,我们的地板上覆盖着塑料杯和水。
让我们在反转控件后尝试:
想象一下,在同一地点举行同一次会议,但我们现在有一个服务员只带一个玻璃杯,而不是塑料杯(Singleton)
当有人想喝酒时,服务员会给他们一杯。他们把它喝了,然后还给服务员。
抛开卫生问题不谈,使用服务员(过程控制)更有效、更经济。
这正是Spring(另一个IoC容器,例如:Guice)所做的。Spring IoC没有让应用程序使用新的关键字(例如,拿一个塑料杯子)创建所需的东西,而是为应用程序提供所需对象(一杯水)的同一杯子/实例(singleton)。
把自己想象成这样一个会议的组织者:
示例:-
public class MeetingMember {
private GlassOfWater glassOfWater;
...
public void setGlassOfWater(GlassOfWater glassOfWater){
this.glassOfWater = glassOfWater;
}
//your glassOfWater object initialized and ready to use...
//spring IoC called setGlassOfWater method itself in order to
//offer to meetingMember glassOfWater instance
}
有用的链接:-
http://adfjsf.blogspot.in/2008/05/inversion-of-control.htmlhttp://martinfowler.com/articles/injection.htmlhttp://www.shawn-barrett.com/blog/post/Tip-of-the-day-e28093-Inversion-Of-Control.aspx
控制反转是当程序回调时得到的结果,例如gui程序。
例如,在旧学校菜单中,您可能有:
print "enter your name"
read name
print "enter your address"
read address
etc...
store in database
从而控制用户交互的流程。
在GUI程序或类似程序中,我们会说:
when the user types in field a, store it in NAME
when the user types in field b, store it in ADDRESS
when the user clicks the save button, call StoreInDatabase
所以现在控制反转了。。。代替计算机以固定的顺序接受用户输入,用户控制输入数据的顺序以及数据保存在数据库中的时间。
基本上,任何带有事件循环、回调或执行触发器的东西都属于这一类。