当第一次遇到控制反转(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

其他回答

我在使用库或框架的上下文中想到了控制反转。

传统的“控制”方式是我们构建一个控制器类(通常是主类,但也可以是任何类型的),导入一个库,然后使用您的控制器类来“控制”软件组件的操作。就像你的第一个C/Python程序(继HelloWorld之后)。

import pandas as pd
df = new DataFrame()
# Now do things with the dataframe.

在这种情况下,我们需要知道Dataframe是什么才能使用它。您需要知道要使用什么方法,它的取值方式等等。如果您通过多态性将它添加到自己的类中,或者只是重新调用它,那么您的类将需要Dataframe库才能正常工作。

“控制反转”意味着过程反转。您可以注册类并将其发送回要控制的引擎,而不是您的类控制库、框架或引擎的元素。换句话说,IoC可能意味着我们正在使用代码来配置框架。您也可以将其视为类似于我们在map或filter中使用函数来处理列表中的数据的方式,只是将其应用于整个应用程序。

如果您是构建引擎的人,那么您可能正在使用依赖注入方法(如上所述)来实现这一点。如果你是一个使用引擎的人(更常见),那么你应该能够只声明类,添加适当的符号,让框架为你完成剩下的工作(例如创建路由、分配servlet、设置事件、输出小部件等)。

我已经读了很多关于这一点的答案,但如果有人仍然感到困惑,需要一个额外的“外行术语”来解释IoC,我的看法是:

想象一个父母和孩子彼此交谈。

没有IoC:

*家长:我问你问题时你才能说话,我允许你时你才能行动。

家长:这意味着,如果我不问你,你就不能问我你能不能吃饭、玩、上厕所甚至睡觉。

家长:你想吃吗?

孩子:没有。

家长:好的,我会回来的。等我。

孩子:(想玩,但由于家长没有问题,孩子什么都不会做)。

1小时后。。。

家长:我回来了。你想玩吗?

孩子:是的。

父级:已授予权限。

孩子:(终于可以玩了)。

这个简单的场景解释了控件以父级为中心。孩子的自由受到限制,高度依赖于父母的问题。孩子只有在被要求说话时才能说话,只有在获得许可时才能行动。

使用IoC:

孩子现在有能力提出问题,家长可以回答并获得许可。简单地说就是控制颠倒了!孩子现在可以随时提问,尽管在权限方面仍然依赖于家长,但他不依赖于说话/提问的方式。

从技术上解释,这与console/shell/cmd与GUI交互非常相似。(这是马克·哈里森的答案,排名第二)。在控制台中,您依赖于向您询问/显示的内容,如果不先回答问题,您无法跳转到其他菜单和功能;遵循严格的顺序流程。(编程上这就像一个方法/函数循环)。然而,有了GUI,菜单和功能就被布置好了,用户可以选择所需的任何内容,从而拥有更多的控制权和更少的限制。(以编程方式,菜单在选中并执行操作时具有回调)。

在类中创建对象称为紧密耦合,Spring通过遵循设计模式(DI/IOC)来消除这种依赖性。在其中类的对象是传入构造函数而不是在类中创建的。此外,我们在构造函数中提供了超类引用变量,以定义更一般的结构。

我将写下我对这两个术语的简单理解:

For quick understanding just read examples*

依赖注入(DI):依赖注入通常意味着将方法依赖的对象作为参数传递给方法,而不是让方法创建依赖对象。这在实践中意味着,该方法不直接依赖于特定的实现;任何满足要求的实现都可以作为参数传递。使用此对象可以告诉它们的依赖关系。春天使它成为可能。这导致了松散耦合的应用程序开发。

Quick Example:EMPLOYEE OBJECT WHEN CREATED,
              IT WILL AUTOMATICALLY CREATE ADDRESS OBJECT
   (if address is defines as dependency by Employee object)

控制反转(IoC)容器:这是框架的共同特征,IOC通过其BeanFactory管理java对象——从实例化到销毁-由IoC容器实例化的Java组件称为bean,IoC容器管理bean的范围、生命周期事件以及为其配置和编码的任何AOP特性。

快速示例:控制反转是指获得自由、更大的灵活性和更少的依赖性。当你使用台式电脑时,你是从属的(或者说,受控的)。你必须坐在屏幕前看着屏幕。用键盘打字,用鼠标导航。一个糟糕的书面软件会让你更加痛苦。如果你用笔记本电脑取代了你的桌面,那么你的控制就有点颠倒了。你可以轻松地拿着它四处走动。所以现在你可以用电脑控制你的位置,而不是电脑控制它。

通过实现控制反转,软件/对象消费者可以获得更多的软件/对象控制/选项,而不是被控制或拥有更少的选项。

作为设计指南的控制反转具有以下目的:

某个任务的执行与实现是分离的。每个模块都可以专注于它的设计目的。模块不假设其他系统做什么,而是依赖它们的合同。替换模块对其他模块没有任何副作用,我将在这里保持抽象,您可以访问以下链接以详细了解主题。一个很好的例子

详细说明

只回答第一部分。这是怎么一回事?

控制反转(IoC)意味着先创建依赖项的实例,然后创建类的后一个实例(可选地通过构造函数注入它们),而不是先创建类的实例,再由类实例创建依赖项实例。因此,控制反转反转程序的控制流程。调用者控制程序的控制流,而不是被调用者控制控制流(同时创建依赖项)。