当第一次遇到控制反转(IoC)时,它可能非常令人困惑。
这是怎么一回事?它解决了哪个问题?什么时候使用合适,什么时候不合适?
当第一次遇到控制反转(IoC)时,它可能非常令人困惑。
这是怎么一回事?它解决了哪个问题?什么时候使用合适,什么时候不合适?
当前回答
我已经读了很多关于这一点的答案,但如果有人仍然感到困惑,需要一个额外的“外行术语”来解释IoC,我的看法是:
想象一个父母和孩子彼此交谈。
没有IoC:
*家长:我问你问题时你才能说话,我允许你时你才能行动。
家长:这意味着,如果我不问你,你就不能问我你能不能吃饭、玩、上厕所甚至睡觉。
家长:你想吃吗?
孩子:没有。
家长:好的,我会回来的。等我。
孩子:(想玩,但由于家长没有问题,孩子什么都不会做)。
1小时后。。。
家长:我回来了。你想玩吗?
孩子:是的。
父级:已授予权限。
孩子:(终于可以玩了)。
这个简单的场景解释了控件以父级为中心。孩子的自由受到限制,高度依赖于父母的问题。孩子只有在被要求说话时才能说话,只有在获得许可时才能行动。
使用IoC:
孩子现在有能力提出问题,家长可以回答并获得许可。简单地说就是控制颠倒了!孩子现在可以随时提问,尽管在权限方面仍然依赖于家长,但他不依赖于说话/提问的方式。
从技术上解释,这与console/shell/cmd与GUI交互非常相似。(这是马克·哈里森的答案,排名第二)。在控制台中,您依赖于向您询问/显示的内容,如果不先回答问题,您无法跳转到其他菜单和功能;遵循严格的顺序流程。(编程上这就像一个方法/函数循环)。然而,有了GUI,菜单和功能就被布置好了,用户可以选择所需的任何内容,从而拥有更多的控制权和更少的限制。(以编程方式,菜单在选中并执行操作时具有回调)。
其他回答
对我来说,IoC/DI正在向调用对象推出依赖项。超级简单。
非技术性的答案是,在你打开引擎之前,你可以更换汽车的引擎。如果一切正常(界面),你就很好了。
编程演讲
简单地说,IoC:它是使用接口作为特定对象(例如字段或参数)的一种方式,作为某些类可以使用的通配符。它允许代码的可重用性。
例如,假设我们有两个类:狗和猫。两者具有相同的品质/状态:年龄、体型、体重。因此,我可以创建一个名为AnimalService的服务类,而不是创建一个称为DogService和CatService的服务,它只允许在Dog和Cat使用IAnimal接口时使用它们。
然而,从务实的角度来看,它有一些倒退。
a) 大多数开发人员不知道如何使用它。例如,我可以创建一个名为Customer的类,我可以(使用IDE的工具)自动创建一个称为ICustomer的接口。因此,无论接口是否会被重用,找到一个充满类和接口的文件夹并不罕见。它叫做BLOATED。有些人可能会认为“也许在未来我们可以使用它”-|
b) 它有一些限制。例如,让我们讨论一下Dog和Cat的情况,我想添加一个仅针对狗的新服务(功能)。比方说,我想计算训练一只狗所需的天数(trainDays()),因为猫没用,猫不能训练(我开玩笑)。
b.1)如果我将trainDays()添加到服务AnimalService中,那么它也适用于猫,并且根本无效。
b.2)我可以在trainDays()中添加一个条件,它评估使用的类。但这将彻底打破IoC。
b.3)我可以为新功能创建一个名为DogService的新服务类。但是,这将增加代码的可维护性,因为我们将为Dog提供两类服务(具有类似的功能),这很糟糕。
使用IoC,您不会对对象进行更新。您的IoC容器将做到这一点,并管理它们的生命周期。
它解决了必须手动将一种类型对象的每个实例化更改为另一种类型的问题。
如果您的功能将来可能会发生变化,或者根据中使用的环境或配置而有所不同,则使用此选项是合适的。
例如,任务#1是创建对象。没有IOC概念,任务#1应该由程序员完成。但有了IOC概念后,任务#1将由容器完成。
简而言之,控件从编程器转换为容器。因此,它被称为控制反转。
我在这里找到了一个很好的例子。
假设我们在酒店开会。
我们邀请了很多人,所以我们漏掉了很多壶水和很多塑料杯。
当有人想喝水时,他/她将杯子装满,喝水,然后将杯子扔在地板上。
大约一个小时后,我们的地板上覆盖着塑料杯和水。
让我们在反转控件后尝试:
想象一下,在同一地点举行同一次会议,但我们现在有一个服务员只带一个玻璃杯,而不是塑料杯(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