当第一次遇到控制反转(IoC)时,它可能非常令人困惑。

这是怎么一回事?它解决了哪个问题?什么时候使用合适,什么时候不合适?


当前回答

IoC原则有助于设计松散耦合的类,使其可测试、可维护和可扩展。

其他回答

在使用“控制反转”之前,你应该充分了解它的优点和缺点,如果你这样做,你应该知道为什么要使用它。

赞成的意见:

您的代码被解耦,因此您可以轻松地将接口的实现与其他实现交换它是针对接口而非实现进行编码的强大动力为代码编写单元测试是非常容易的,因为它只依赖于它在构造函数/setter中接受的对象,并且可以很容易地用正确的对象单独初始化它们。

欺骗:

IoC不仅会反转程序中的控制流,还会使其变得相当模糊。这意味着你不能再只读取代码并从一个地方跳到另一个地方,因为代码中通常存在的连接不再存在。相反,它在XML配置文件或注释中以及IoC容器的代码中解释这些元数据。出现了一类新的错误,即您的XML配置或注释错误,您可以花费大量时间来找出IoC容器在特定条件下向其中一个对象注入空引用的原因。

就我个人而言,我看到了IoC的优点,我非常喜欢它们,但我倾向于尽可能避免使用IoC,因为它将您的软件变成一个类的集合,这些类不再构成“真正的”程序,而只是需要通过XML配置或注释元数据组合在一起的东西,如果没有IoC,它就会崩溃。

假设你是一个物体。然后你去餐馆:

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

与IoC:你可以要求“水果”。每次上桌你都可以得到不同的水果。例如,苹果、橙子或西瓜。

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

IoC原则有助于设计松散耦合的类,使其可测试、可维护和可扩展。

我知道这里已经给出了答案。但我仍然认为,关于控制反转的一些基础知识必须在这里详细讨论,以供未来读者参考。

控制反转(IoC)建立在一个叫做好莱坞原理的非常简单的原理上。上面说,

不要给我们打电话,我们会给你打电话

这意味着不要去好莱坞实现你的梦想,如果你值得,那么好莱坞会找到你,让你的梦想成真。差不多颠倒了,嗯?

现在,当我们讨论IoC的原理时,我们常常忘记好莱坞。对于IoC来说,必须有三个要素,一个好莱坞,一个你和一个完成你梦想的任务。

在我们的编程世界中,Hollywood代表一个通用框架(可能由您或其他人编写),您代表您编写的用户代码,任务代表您希望用代码完成的任务。现在,你永远不会自己触发任务,而不是在IoC!相反,你已经设计好了所有的东西,这样你的框架就会触发你的任务。因此,您已经构建了一个可重用的框架,它可以使某人成为英雄或另一人成为恶棍。但这一框架始终处于主导地位,它知道什么时候该挑选某人,而某人只知道自己想要成为什么样的人。

这里将给出一个真实的例子。假设您想开发一个web应用程序。因此,您可以创建一个框架来处理web应用程序应该处理的所有常见事务,如处理http请求、创建应用程序菜单、服务页面、管理cookie、触发事件等。

然后你在你的框架中留下一些钩子,你可以在那里放置更多的代码来生成自定义菜单、页面、cookie或记录一些用户事件等。在每次浏览器请求时,你的框架都会运行并执行你的自定义代码,如果勾住了,然后将其发送回浏览器。

所以,这个想法非常简单。与其创建一个控制一切的用户应用程序,不如先创建一个可重用的框架来控制一切,然后编写自定义代码并将其连接到框架以及时执行这些代码。

Laravel和EJB就是这样一个框架的例子。

参考:

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

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

由于这个问题已经有很多答案,但没有一个显示反转控制项的分解,我认为有机会给出一个更简洁和有用的答案。

控制反转是一种实现依赖反转原理(DIP)的模式。DIP声明如下:1。高级模块不应依赖于低级模块。两者都应该依赖于抽象(例如接口)。2.摘要不应依赖于细节。细节(具体实现)应该依赖于抽象。

控制反转有三种类型:

界面反转提供程序不应定义接口。相反,使用者应该定义接口,提供者必须实现它。接口反转允许消除每次添加新提供者时修改使用者的必要性。

流量反演更改流量控制。例如,您有一个控制台应用程序,要求输入许多参数,在输入每个参数后,您必须按enter键。您可以在此处应用Flow Inversion,并实现桌面应用程序,用户可以选择输入参数的顺序,用户可以编辑参数,在最后一步,用户只需按Enter键一次。

创建反转它可以通过以下模式实现:工厂模式、服务定位器和依赖注入。创建反转有助于消除类型之间的依赖关系,将依赖关系对象创建过程移到使用这些依赖关系对象的类型之外。为什么依赖关系不好?这里有几个例子:在代码中直接创建一个新对象会使测试更加困难;不重新编译就不可能更改程序集中的引用(违反OCP原则);你不能轻易地用web UI替换桌面UI。