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

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


当前回答

所以上面的数字1。什么是控制反转?维护是它为我解决的首要问题。它保证我使用的是接口,这样两个类就不会彼此亲密。

使用温莎城堡这样的容器,它可以更好地解决维护问题。能够在不更改一行代码的情况下,将一个连接到数据库的组件替换为一个使用基于文件的持久性的组件,这是非常棒的(配置更改完成了)。

一旦你进入泛型,它会变得更好。想象一下,拥有一个接收记录并发布消息的消息发布者。它不在乎它发布了什么,但它需要一个映射器将记录中的内容转换为消息。

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

我写过一次,但现在如果我发布不同类型的消息,我可以向这组代码中注入许多类型。我还可以编写映射器,将相同类型的记录映射到不同的消息。将DI与Generics结合使用使我能够编写很少的代码来完成许多任务。

哦,是的,存在可测试性问题,但它们比IoC/DI的优势更为次要。

我绝对喜欢IoC/DI。

3.当你有一个中等规模的项目时,它会变得更加合适。我会说,当你开始感到疼痛时,它就变得合适了。

其他回答

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

就像这个例子中的TextEditor一样:如果你只有一个拼写检查器,那么可能真的没有必要使用IoC?除非你需要写单元测试之类的。。。

无论如何:要讲道理。设计模式是很好的实践,但不是圣经。不要把它粘在任何地方。

为了理解IoC,我们应该讨论依赖反转。

依赖反转:依赖于抽象,而不是具体。

控制反转:主与抽象,以及主如何成为系统的粘合剂。

我写了一些很好的例子,你可以在这里查看:

https://coderstower.com/2019/03/26/dependency-inversion-why-you-shouldnt-avoid-it/

https://coderstower.com/2019/04/02/main-and-abstraction-the-decoupled-peers/

https://coderstower.com/2019/04/09/inversion-of-control-putting-all-together/

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

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特性。

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

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

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

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

详细说明

真的不明白为什么会有很多错误的答案,甚至被接受的答案也不太准确,这让人很难理解。真相总是简单明了的。

正如@Schneider在@Mark Harrison的回答中所评论的,请阅读Martin Fowler关于IoC的帖子。

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

我最喜欢的是:

这种现象就是控制反转(也称为好莱坞原则——“不要打电话给我们,我们会打电话给你”)。

为什么?

IoC的Wiki,我可以引用一段话。

控制反转用于增加程序的模块性并使其可扩展。。。随后在2004年由Robert C.Martin和Martin Fowler进一步推广。

Robert C.Martin:《清洁代码:敏捷软件工艺手册》的作者。

马丁·福勒:《重构:改进现有代码的设计》一书的作者。

这是怎么一回事?反转(耦合)控制,更改方法签名的耦合方向。对于反向控制,方法签名的定义由方法实现(而不是方法的调用方)决定。此处完整解释

它解决了哪个问题?方法上的自顶向下耦合。这随后消除了重构的需要。

什么时候使用合适,什么时候不合适?对于定义良好的小型应用程序,如果没有太大的变化,可能会产生开销。然而,对于将要发展的定义较少的应用程序,它减少了方法签名的固有耦合。这使开发人员可以更自由地开发应用程序,避免了对代码进行昂贵的重构。基本上,允许应用程序在很少返工的情况下发展。