什么是控制反转?

控制反转(或IoC)在第一次遇到时可能会相当混乱。

  1. 它是什么?
  2. 它解决了什么问题?
  3. 什么时候适合,什么时候不适合?

控制反转(IoC)和dependency injection(DI)模式都是从你的代码中去除依赖。

例如,说你的应用程序有一个文本编辑器组件,你想提供拼写检查。 你的标准代码看起来像这样:

public class TextEditor { private SpellChecker checker; public TextEditor() { this.checker = new SpellChecker(); } } 

我们在这里做的是在TextEditorSpellChecker之间创build一个依赖关系。 在IoC的情况下,我们会做这样的事情:

 public class TextEditor { private IocSpellChecker checker; public TextEditor(IocSpellChecker checker) { this.checker = checker; } } 

在第一个代码示例中,我们正在实例化this.checker = new SpellChecker();this.checker = new SpellChecker(); ),这意味着TextEditor类直接依赖于SpellChecker类。

在第二个代码示例中,我们通过在TextEditor构造函数签名中具有SpellChecker依赖类(不初始化类中的依赖项)来创build抽象。 这允许我们调用依赖关系,然后将其传递给TextEditor类,如下所示:

 SpellChecker sc = new SpellChecker; // dependency TextEditor textEditor = new TextEditor(sc); 

现在,创buildTextEditor类的客户端可以控制使用哪个SpellChecker实现,因为我们正在向TextEditor签名注入依赖项。

这只是一个简单的例子,Simone Busoli有一系列的文章详细解释了它。

控制反转就是你的程序callback,比如gui程序。

例如,在旧的学校菜单中,您可能会有:

 print "enter your name" read name print "enter your address" read address etc... store in database 

从而控制用户交互的stream程。

在一个graphics用户界面程序或其他一些,而是我们说

 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 

所以现在控制被反转了…而不是以固定顺序接受用户input的计算机,用户控制input数据的顺序,以及当数据被保存在数据库中时。

基本上,任何事件循环,callback或执行触发器都属于这个类别。

什么是控制反转?

如果你遵循这些简单的两个步骤,你已经做了控制反转:

  1. 分离什么是做什么的部分从什么时候做。
  2. 确保部件尽可能less知道一部分; 反之亦然。

根据您正在使用的技术/语言,每个步骤都有几种可能的技术。

控制反转(IoC)的反转部分是令人困惑的事情; 因为倒置是相对的术语。 了解IoC的最好方法就是忘掉这个词!

例子

  • 事件处理。 事件处理器(What-to-do part) – 提高事件(当做事情的一部分)
  • 接口。 组件客户端(当要做的部分) – 组件接口的实现(做什么的部分)
  • xUnit固定。 安装程序和TearDown(做什么的一部分) – xUnit框架在开始时调用安装程序,在最后(即将做的部分)调用TearDown,
  • 模板方法devise模式。 模板方法什么时候做部分 – 原始子类实现什么部分
  • COM中的DLL容器方法 DllMain,DllCanUnload等(做什么) – COM / OS(什么时候做)

在使用Inversion of Control之前,你应该清楚它有其优点和缺点,你应该知道你为什么使用它。

优点:

  • 您的代码被解耦,因此您可以轻松地将接口的实现与其他实现交换
  • 这是对接口而不是实现进行编码的强大动力
  • 为你的代码编写unit testing非常容易,因为它不依赖于它在构造函数/设置器中接受的对象,你可以很容易地用正确的对象单独初始化它们。

缺点:

  • IoC不仅会颠倒您的程序中的控制stream,而且还会大大地增加控制stream。 这意味着您不能再读取您的代码并从一个地方跳到另一个地方,因为通常在您的代码中的连接不在代码中。 而是在XMLconfiguration文件或注释中以及解释这些元数据的IoC容器的代码中。
  • 出现了一个新的类错误,你得到你的XMLconfiguration或你的注解错误,你可以花费大量的时间找出为什么你的IoC容器注入一个空引用到你的对象之一在某些条件下。

就我个人而言,我看到了IoC的优点,我真的很喜欢它们,但是我倾向于尽可能避免IoC,因为它会将您的软件变成一个不再构成“真实”程序的类集合,而只是需要通过XMLconfiguration或注释元数据,如果没有它,就会掉落(和掉落)。

控制反转(IoC)是关于获得自由 (你结婚了,你失去了自由,你被控制了,你离婚了,你刚刚实现了控制反转,这就是我们所说的“解耦”。不鼓励一些非常密切的关系) 更大的灵活性 (你的办公室里的厨房只提供干净的自来水,这是你想要喝的唯一select,你的老板通过build立一台新的咖啡机来实现控制反转。灵活性select自来水或咖啡)和较less的依赖性 (你的伴侣有一份工作,你没有工作,你在经济上依赖于你的伴侣,所以你是受控制的。你find一份工作,你已经实施了反转控制良好的计算机系统鼓励依赖性。)

当你使用台式电脑,你从属(或说,控制)。 你必须坐在一个屏幕前,看看它。 使用键盘input并使用鼠标进行导航。 而一个写得不好的软件可以奴役你甚至更多。 如果你用一台笔记本电脑来replace你的桌面,那么你有点颠倒了控制。 你可以轻松地把它移动。 所以现在你可以控制你的计算机,而不是你的计算机控制它。

通过实施控制反转(Inversion of Control),软件/对象消费者获得对软件/对象更多的控制/select,而不是被控制或具有更less的选项。

有了上述的想法。 我们仍然错过了IoC的关键部分。 在IoC的情况下,软件/对象消费者是一个复杂的框架。 这意味着你创build的代码不是你自己调用的。 现在我们来解释为什么这种方式对Web应用程序更好。

假设你的代码是一群工人。 他们需要build一辆车。 这些工人需要一个地方和工具(一个软件框架)来build造汽车。 传统的软件框架将像一个拥有许多工具的车库。 所以工作人员需要自己制定计划,并使用工具来build造汽车。 build车不是一件容易的事情,工人的计划和合作确实很难。 一个现代化的软件框架就像一个现代化的汽车工厂,所有的设施和pipe理人员都已到位。 工作人员不必制定任何计划,pipe理人员(框架的一部分,他们是最聪明的人,制定最复杂的计划)将有助于协调工作人员知道何时完成工作(框架称为您的代码)。 工作人员只需要足够的灵活性来使用pipe理员给他们的任何工具(通过使用dependency injection)。

虽然工人们把pipe理顶层项目的pipe理权交给了pipe理者(框架)。 但有一些专业人士帮忙是很好的。 这是IoC真正来自的概念。

具有MVC体系结构的现代Web应用程序依赖于执行URL路由的框架,并将控制器置于框架中以供调用。

控制的dependency injection和反转是相关的。 dependency injection处于微观层面,控制反转处于macros观层面。 你必须吃每一口(执行DI)才能完成一顿饭(执行IoC)。

控制反转是关于分离问题。

没有IoC :你有一台笔记本电脑,你不小心打破了屏幕。 而且,你会发现,同样型号的笔记本电脑屏幕在市场上并不存在。 所以你卡住了

使用IoC :你有一台台式电脑,意外地破坏了屏幕。 你会发现你几乎可以从市场上购买任何台式机显示器,而且它可以和你的台式机配合使用。

在这种情况下,您的桌面成功实现了IoC。 它接受各种types的显示器,而笔记本电脑不,它需要一个特定的屏幕才能得到修复。

  1. 维基百科的文章 。 对我来说,控制反转就是把你顺序编写的代码变成一个委托结构。 而不是你的程序明确地控制一切,你的程序build立一个类或图书馆具有某些function的特定事情发生时被调用。

  2. 它解决了代码重复。 例如,在过去,您可以手动编写自己的事件循环,轮询系统库中的新事件。 如今,大多数现代化的API只需告诉系统库你感兴趣的事件,它会让你知道什么时候发生。

  3. 控制反转是减less代码重复的实用方法,如果您发现自己复制了整个方法并只更改了一小段代码,则可以考虑通过控制反转来解决这个问题。 通过委托,接口甚至原始函数指针的概念,控制反转在许多语言中变得容易。

    在所有情况下使用都是不恰当的,因为用这种方式编写程序时,stream程很难遵循。 在编写将被重用的库时,devise方法是一种非常有用的方法,但是除非它真正解决了代码重复问题,否则应该在自己的程序的核心中谨慎使用。

但我认为你必须非常小心。 如果你过度使用这种模式,你会做出非常复杂的devise和更复杂的代码。

就像在这个使用TextEditor的例子中一样:如果你只有一个SpellChecker,那么使用IoC是不是真的有必要? 除非你需要编写unit testing或其他东西…

无论如何:合理。 devise模式是好的做法,但不是要传讲圣经。 不要把它粘在任何地方。

IoC / DI对我来说是推出依赖到调用对象。 超级简单。

非技术的答案是能够在开车之前将汽车中的发动机换掉。 如果一切正确(界面),你是好的。

假设你是一个对象。 你去一家餐馆

没有IoC :你要求“苹果”,当你问得更多时,你总是被送到苹果。

IoC :你可以要求“水果”。 每次送达时都可以得到不同的水果。 例如苹果,桔子或西瓜。

所以,显然,当你喜欢品种时,IoC是首选。

  1. 控制反转是用于解耦系统中的组件和层的模式。 该模式是通过在组件中注入依赖关系来实现的。 这些依赖通常被提供为进一步解耦和支持可测性的接口。 IoC / DI容器,如Castle Windsor,Unity是可用于提供IoC的工具(库)。 这些工具提供了超出简单依赖pipe理的扩展function,包括生命周期,AOP /拦截,策略等。

  2. 一个。 减轻组件负责pipe理它的依赖性。
    湾 提供在不同环境中交换依赖项实现的能力。
    C。 允许通过嘲弄依赖来testing组件。
    d。 提供一种在整个应用程序中共享资源的机制。

  3. 一个。 进行testing驱动开发时很关键。 没有IoC,可能很难testing,因为被测组件与系统的其他部分高度耦合。
    湾 在开发模块化系统时很关键 模块化系统是一个系统,其组件可以被replace而不需要重新编译。
    C。 如果有许多需要解决的交叉问题,这在企业应用程序中也是如此。

例如,任务#1是创build对象。 没有国际奥委会的概念,任务#1应该由程序员来完成。但是随着国际奥委会的概念,任务#1将由容器完成。

简而言之,控制从程序员转换到容器。 所以被称为控制反转。

我在这里find一个很好的例子。

看起来最令人困惑的是,“IoC”这个名字的缩写和名字太过于迷人了 – 几乎就是一个噪音的名字。

我们真的需要一个名字来描述程序和事件驱动的编程之间的区别吗? 好的,如果我们需要的话,但是我们是否需要select一个全新的“比人生更伟大”的名字,而这个名字比解决问题更困难?

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

 For quick understanding just read examples* 

dependency injection(DI):
dependency injection一般意味着将方法所依赖的对象作为parameter passing给方法,而不是让方法创build依赖对象
这在实践中意味着该方法不直接依赖于特定的实现; 任何满足要求的实现都可以作为parameter passing。

用这个对象来告诉他们的依赖关系。 而spring使它可用。
这导致了松耦合的应用程序开发。

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

控制反转(IoC)容器:
这是框架的共同特点,IOC pipe理java对象
从实例化到通过BeanFactory的销毁。
-Java组件由IoC容器实例化,称为bean, IoC容器pipe理一个bean的范围,生命周期事件以及它已经被configuration和编码的任何AOP特性

QUICK EXAMPLE:Inversion of Control is about getting freedom, more flexibility, and less dependency. When you are using a desktop computer, you are slaved (or say, controlled). You have to sit before a screen and look at it. Using keyboard to type and using mouse to navigate. And a bad written software can slave you even more. If you replaced your desktop with a laptop, then you somewhat inverted control. You can easily take it and move around. So now you can control where you are with your computer, instead of computer controlling it QUICK EXAMPLE:Inversion of Control is about getting freedom, more flexibility, and less dependency. When you are using a desktop computer, you are slaved (or say, controlled). You have to sit before a screen and look at it. Using keyboard to type and using mouse to navigate. And a bad written software can slave you even more. If you replaced your desktop with a laptop, then you somewhat inverted control. You can easily take it and move around. So now you can control where you are with your computer, instead of computer controlling it

通过实施控制反转(Inversion of Control),软件/对象消费者获得对软件/对象的更多控制/select,而不是被控制或具有更less的选项。

控制反转作为devise指南服务于以下目的:

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

详细的解释

我同意NilObject ,但我想补充一点:

如果你发现自己复制整个方法,只改变一小段代码,你可以考虑用反转控制来解决这个问题

如果你发现自己复制和粘贴代码,你几乎总是做错了什么 。 作为devise原则一次又一次的编码。

让我们说,我们在一些酒店做一些会议。

许多人,许多水瓶,许多塑料杯。

当有人想要喝酒时,她会把杯子放进杯子里,然后把杯子丢在地上。

一小时之后,我们有一个地面覆盖着塑料杯和水。

让反转控制。

在同一个地方同样的会议,而不是塑料杯,我们有一个玻璃杯(单身)的服务员,

而她所有的时间都提供给客人喝酒。

当有人想喝酒的时候,她从服务员的玻璃杯里拿出来喝,然后把它还给服务员。

撇开卫生问题,饮用过程控制的最后一种forms是更为有效和经济的。

而这正是Spring(另一个IoC容器,例如:Guice)所做的。 而不是让应用程序使用新的关键字(取塑料杯)来创build它所需要的,Spring IoC容器一直为应用程序提供所需对象(glass of water)的相同实例(singleton)。

想想你自己是这种会议的组织者。 你需要通知酒店pipe理部门

会议成员将需要一杯水,而不是一块蛋糕。

例:-

 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 } 

有用的链接: –

IoC是关于反转你的代码和第三方代码(库/框架)之间的关系的:

  • 在正常的软件开发中,你编写main()方法并调用“库”方法。 在控制:)
  • 在IoC中,“框架”控制main()并调用你的方法。 该框架是在控制:(

DI(dependency injection)是关于应用程序中的控制stream程。 传统的桌面应用程序有控制stream从你的应用程序(main()方法)到其他库方法调用,但是DI控制stream是倒转的,框架负责启动你的应用程序,初始化它,并在需要时调用你的方法。

最后你总是赢得:)

一个非常简单的书面解释可以在这里find

http://binstock.blogspot.in/2008/01/excellent-explanation-of-dependency.html

它说

“任何非平凡的应用程序都由两个或更多的类组成,这些类彼此合作来执行一些业务逻辑。传统上,每个对象都负责获取它自己与它合作的对象(它的依赖关系)的引用。对象在创build时由一些协调系统中每个对象的外部实体赋予它们的依赖关系,换句话说,依赖关系被注入到对象中。

编程说话

IoC简单来说:就是将接口用作某种特定事物(如字段或参数)的一种方式,作为某些类可以使用的通配符。 它允许代码的可重用性。

例如,假设我们有两个类: DogCat 。 两者具有相同的品质/状态:年龄,身材,体重。 因此,我们可以创build一个名为AnimalService的服务,而不是创build一个名为DogServiceCatService的服务,只有在使用接口IAnimal时才允许使用Dog和Cat。

但是,务实地说,它有一些倒退。

a) 大多数开发人员不知道如何使用它 。 例如,我可以创build一个名为Customer的类,并且可以自动创build一个名为ICustomer的接口(使用IDE的工具)。 所以,find一个充满类和接口的文件夹并不罕见,不pipe接口是否被重用。 这叫做BLOATED。 有些人可能会争辩说“未来可能会使用它”。 : – |

b)有一些限制。 例如,让我们来谈谈的情况,我想为狗添加一个新的服务(function)。 比方说,我想计算我需要训练一只狗( trainDays() )的天数,对于猫来说它是没用的,猫不能被训练(我在开玩笑)。

b.1)如果我将trainDays()添加到Service AnimalService,那么它也适用于猫,它根本就没有任何作用。

b.2)我可以在trainDays()中添加一个条件来评估哪个类被使用。 但它将完全打破IoC。

b.3)我可以创build一个名为DogService的新服务类,仅用于新function。 但是,这会增加代码的可维护性,因为我们将为Dog提供两类服务(具有类似的function),这很糟糕。

只回答第一部分。 它是什么?

控制反转(IoC)意味着创build一个类的第一个和第二个实例的依赖关系的实例(可选地通过构造函数注入它们),而不是先创build一个类的实例,然后创build依赖关系实例。 因此,控制反转颠倒了程序的控制stream程调用者控制程序的控制 stream程, 而不是 调用者控制 stream程 (创build依赖关系时)。

控制反转是一个通用的原则,而dependency injection实现这个原则作为对象图构造的devise模式(即configuration控制对象如何相互引用,而不是控制如何获得对另一个对象的引用的对象本身)。

将控制反转看作devise模式,我们需要看看我们正在反转的是什么。 dependency injection反转了构造对象图的控制。 如果用外行人的话来说,控制的倒置意味着程序中控制stream程的改变。 例如。 In traditional standalone app, we have main method, from where the control gets passed to other third party libraries(in case, we have used third party library's function), but through inversion of control control gets transferred from third party library code to our code, as we are taking the service of third party library. But there are other aspects that need to be inverted within a program – eg invocation of methods and threads to execute the code.

For those interested in more depth on Inversion of Control a paper has been published outlining a more complete picture of Inversion of Control as a design pattern (OfficeFloor: using office patterns to improve software design http://doi.acm.org/10.1145/2739011.2739013 with a free copy available to download from http://www.officefloor.net/mission.html )

What is identified is the following relationship:

Inversion of Control (for methods) = Dependency (state) Injection + Continuation Injection + Thread Injection

  1. So number 1 above . 什么是控制反转?

  2. Maintenance is the number one thing it solves for me. It guarantees I am using interfaces so that two classes are not intimate with each other.

In using a container like Castle Windsor, it solves maintenance issues even better. Being able to swap out a component that goes to a database for one that uses file based persistence without changing a line of code is awesome (configuration change, you're done).

And once you get into generics, it gets even better. Imagine having a message publisher that receives records and publishes messages. It doesn't care what it publishes, but it needs a mapper to take something from a record to a message.

 public class MessagePublisher<RECORD,MESSAGE> { public MessagePublisher(IMapper<RECORD,MESSAGE> mapper,IRemoteEndpoint endPointToSendTo) { //setup } } 

I wrote it once, but now I can inject many types into this set of code if I publish different types of messages. I can also write mappers that take a record of the same type and map them to different messages. Using DI with Generics has given me the ability to write very little code to accomplish many tasks.

Oh yeah, there are testability concerns, but they are secondary to the benefits of IoC/DI.

I am definitely loving IoC/DI.

3。 It becomes more appropriate the minute you have a medium sized project of somewhat more complexity. I would say it becomes appropriate the minute you start feeling pain.

Creating an object within class is called tight coupling, Spring removes this dependency by following a design pattern(DI/IOC). In which object of class in passed in constructor rather than creating in class. More over we give super class reference variable in constructor to define more general structure.

To understanding the concept, Inversion of Control (IoC) or Dependency Inversion Principle (DIP) involves two activities: abstraction, and inversion. Dependency Injection (DI) is just one of the few of the inversion methods.

To read more about this you can read my blog Here

  1. 它是什么?

It is a practice where you let the actual behavior come from outside of the boundary (Class in Object Oriented Programming). The boundary entity only knows the abstraction (eg interface, abstract class, delegate in Object Oriented Programming) of it.

  1. 它解决了什么问题?

In term of programming, IoC try to solve monolithic code by making it modular, decoupling various parts of it, and make it unit-testable.

  1. 什么时候适合,什么时候不适合?

It is appropriate most of the time, unless you have situation where you just want monolithic code (eg very simple program)

I like this explanation: http://joelabrahamsson.com/inversion-of-control-an-introduction-with-examples-in-net/

It start simple and shows code examples as well.

在这里输入图像描述

The consumer, X, needs the consumed class, Y, to accomplish something. That's all good and natural, but does X really need to know that it uses Y?

Isn't it enough that X knows that it uses something that has the behavior, the methods, properties etc, of Y without knowing who actually implements the behavior?

By extracting an abstract definition of the behavior used by X in Y, illustrated as I below, and letting the consumer X use an instance of that instead of Y it can continue to do what it does without having to know the specifics about Y.

在这里输入图像描述

In the illustration above Y implements I and X uses an instance of I. While it's quite possible that X still uses Y what's interesting is that X doesn't know that. It just knows that it uses something that implements I.

Read article for further info and description of benefits such as:

  • X is not dependent on Y anymore
  • More flexible, implementation can be decided in runtime
  • Isolation of code unit, easier testing

IoC is also known as dependency injection (DI). It is a process whereby objects define their dependencies, that is, the other objects they work with, only through constructor arguments, arguments to a factory method, or properties that are set on the object instance after it is constructed or returned from a factory method. The container then injects those dependencies when it creates the bean. This process is fundamentally the inverse, hence the name Inversion of Control (IoC), of the bean itself controlling the instantiation or location of its dependencies by using direct construction of classes, or a mechanism such as the Service Locator pattern

Spring-framework-referance.pfd page 34

spring/docs/3.0.x/spring-framework-reference/pdf/spring-framework-reference.pdf

Using IoC you are not new'ing up your objects. Your IoC container will do that and manage the lifetime of them.

It solves the problem of having to manually change every instantiation of one type of object to another.

It is appropriate when you have functionality that may change in the future or that may be different depending on the environment or configuration used in.

The very first version of Java EE (J2EE at the time) introduced the concept of inversion of control (IoC), meaning that the container would take control of your business code and provide technical services (such as transaction or security management).

I found a very clear example here which explains how the 'control is inverted'.

Classic code (without Dependency injection)

Here is how a code not using DI will roughly work:

  • Application needs Foo (eg a controller), so:
  • Application creates Foo
  • Application calls Foo
    • Foo needs Bar (eg a service), so:
    • Foo creates Bar
    • Foo calls Bar
      • Bar needs Bim (a service, a repository, …), so:
      • Bar creates Bim
      • Bar does something

Using dependency injection

Here is how a code using DI will roughly work:

  • Application needs Foo, which needs Bar, which needs Bim, so:
  • Application creates Bim
  • Application creates Bar and gives it Bim
  • Application creates Foo and gives it Bar
  • Application calls Foo
    • Foo calls Bar
      • Bar does something

The control of the dependencies is inverted from one being called to the one calling.

What problems does it solve?

Dependency injection makes it easy to swap with the different implementation of the injected classes. While unit testing you can inject a dummy implementation, which makes the testing a lot easier.

Ex: Suppose your application stores the user uploaded file in the Google Drive, with DI your controller code may look like this:

 class SomeController { private $storage; function __construct(StorageServiceInterface $storage) { $this->storage = $storage; } public function myFunction () { return $this->storage->getFile($fileName); } } class GoogleDriveService implements StorageServiceInterface { public function authenticate($user) {} public function putFile($file) {} public function getFile($file) {} } 

When your requirements change say, instead of GoogleDrive you are asked to use the Dropbox. You only need to write a dropbox implementation for the StorageServiceInterface. You don't have make any changes in the controller as long as Dropbox implementation adheres to the StorageServiceInterface.

While testing you can create the mock for the StorageServiceInterface with the dummy implementation where all the methods return null(or any predefined value as per your testing requirement).

Instead if you had the controller class to construct the storage object with the new keyword like this:

 class SomeController { private $storage; function __construct() { $this->storage = new GoogleDriveService(); } public function myFunction () { return $this->storage->getFile($fileName); } } 

When you want to change with the Dropbox implementation you have to replace all the lines where new GoogleDriveService object is constructed and use the DropboxService. Besides when testing the SomeController class the constructor always expects the GoogleDriveService class and the actual methods of this class are triggered.

When is it appropriate and when not? In my opinion you use DI when you think there are (or there can be) alternative implementations of a class.

I understand that the answer has already been given here. But I still think, some basics about the inversion of control have to be discussed here in length for future readers.

Inversion of Control (IoC) has been built on a very simple principle called Hollywood Principle . And it says that,

Don't call us, we'll call you

What it means is that don't go to the Hollywood to fulfill your dream rather if you are worthy then Hollywood will find you and make your dream comes true. Pretty much inverted, huh?

Now when we discuss about the principle of IoC, we use to forget about the Hollywood. For IoC, there has to be three element, a Hollywood, you and a task like to fulfill your dream.

In our programming world, Hollywood represent a generic framework (may be written by you or someone else), you represent the user code you wrote and the task represent the thing you want to accomplish with your code. Now you don't ever go to trigger your task by yourself, not in IoC! Rather you have designed everything in such that your framework will trigger your task for you. Thus you have built a reusable framework which can make someone a hero or another one a villain. But that framework is always in charge, it knows when to pick someone and that someone only knows what it wants to be.

A real life example would be given here. Suppose, you want to develop a web application. So, you create a framework which will handle all the common things a web application should handle like handling http request, creating application menu, serving pages, managing cookies, triggering events etc.

And then you leave some hooks in your framework where you can put further codes to generate custom menu, pages, cookies or logging some user events etc. On every browser request, your framework will run and executes your custom codes if hooked then serve it back to the browser.

So, the idea is pretty much simple. Rather than creating a user application which will control everything, first you create a reusable framework which will control everything then write your custom codes and hook it to the framework to execute those in time.

Laravel and EJB are examples of such a frameworks.

参考:

https://martinfowler.com/bliki/InversionOfControl.html

https://en.wikipedia.org/wiki/Inversion_of_control