什么是控制反转?
第一次遇到控制反转(或者IoC)时,可能会很混乱。
- 它是什么?
- 它解决什么问题?
- 什么时候合适,什么时候不合适?
解决方案
回答
- 维基百科文章。对我来说,控制权的转换是将我们顺序编写的代码转换为委派结构。程序没有设置明确控制所有内容的程序,而是设置了具有某些功能的类或者库,以在发生某些事情时调用它们。
- 它解决了代码重复。例如,在过去,我们将手动编写自己的事件循环,在系统库中轮询新事件。如今,大多数现代API只需告诉系统库我们感兴趣的事件,它就会在事件发生时通知我们。
- 控制反转是减少代码重复的一种实用方法,如果我们发现自己复制了整个方法而只更改了一小段代码,则可以考虑使用控制反转来解决它。通过代理,接口甚至原始函数指针的概念,在许多语言中,控制反转都变得很容易。不适合在所有情况下使用,因为以这种方式编写程序时,流程很难遵循。这是编写将被重用的库时设计方法的一种有用方法,但是除非真正解决了代码重复问题,否则应在我们自己程序的核心中谨慎使用。
回答
我同意NilObject,但我想补充一点:
if you find yourself copying an entire method and only changing a small piece of the code, you can consider tackling it with inversion of control
如果我们发现自己正在复制和粘贴代码,那么我们几乎总是在做错事。编入设计原则一次,也只有一次。
回答
当程序回调时,我们将获得控制反转。像gui程序一样。
例如,在旧的学校菜单中,我们可能具有:
print "enter your name" read name print "enter your address" read address etc... store in database
从而控制用户交互的流程。
在GUI程序或者类似程序中,我们说
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
因此,现在控制权被颠倒了……而不是计算机按照固定的顺序接受用户输入,而是由用户控制输入数据的顺序以及何时将数据保存在数据库中。
基本上,任何带有事件循环,回调或者执行触发器的东西都属于此类。
回答
控制反转(IoC)和依赖注入(DI)模式都是关于从代码中删除依赖的。
例如,假设应用程序具有文本编辑器组件,而我们想提供拼写检查。标准代码如下所示:
public class TextEditor { private SpellChecker checker; public TextEditor() { this.checker = new SpellChecker(); } }
我们在这里所做的创建了TextEditor和SpellChecker之间的依赖关系。
在IoC场景中,我们改为执行以下操作:
public class TextEditor { private IocSpellChecker checker; public TextEditor(IocSpellChecker checker) { this.checker = checker; } }
在第一个代码示例中,我们实例化了" SpellChecker"(" this.checker = new SpellChecker();"),这意味着" TextEditor"类直接依赖于" SpellChecker"类。
在第二个代码示例中,我们通过在TextEditor构造函数签名中具有SpellChecker依赖项类(而不是在类中初始化依赖项)来创建抽象。这使我们可以调用依赖项,然后将其传递给TextEditor类,如下所示:
SpellChecker sc = new SpellChecker; // dependency TextEditor textEditor = new TextEditor(sc);
现在,创建TextEditor类的客户端可以控制要使用哪个SpellChecker实现,因为我们正在将依赖项注入到TextEditor签名中。
这只是一个简单的示例,Simone Busoli撰写了一系列不错的文章,对其进行了更详细的说明。
回答
但是我认为我们必须非常小心。如果我们将过度使用此模式,则将进行非常复杂的设计,甚至是更加复杂的代码。
就像在本示例中使用TextEditor一样:如果我们只有一个SpellChecker,也许不是真的需要使用IoC吗?除非我们需要编写单元测试之类的东西,否则...
无论如何:合理。设计模式是好的做法,但不是要宣扬的圣经。请勿将其粘在任何地方。
回答
- 控制反转是用于解耦系统中组件和层的一种模式。该模式是通过在构造组件时将依赖项注入到组件中来实现的。这些依赖关系通常作为进一步去耦和支持可测试性的接口提供。 IoC / DI容器(例如温莎城堡,Unity)是可用于提供IoC的工具(库)。这些工具提供了超出简单依赖管理之外的扩展功能,包括生存期,AOP /拦截,策略等。
- 一种。减轻了负责管理其依赖项的组件的负担。 b。提供在不同环境中交换依赖关系实现的功能。 C。允许通过模拟依赖项来测试组件。 d。提供一种在整个应用程序中共享资源的机制。
- 一种。在进行测试驱动的开发时至关重要。没有IoC,可能很难进行测试,因为被测组件与系统的其余部分高度耦合。 b。开发模块化系统时至关重要。模块化系统是无需重新编译即可更换组件的系统。 C。至关重要的是,在企业应用程序中是否存在许多需要解决的跨领域问题。
回答
我的IoC / DI正在推出对调用对象的依赖关系。超级简单。
绝妙的答案是能够在打开汽车之前就将其换掉。如果一切正常(界面),那么我们就很好。
回答
- 所以上面的第一。什么是控制反转?
- 维护是它为我解决的第一件事。它保证了我正在使用接口,以便两个类彼此之间不亲密。
通过使用诸如温莎城堡的容器,它可以更好地解决维护问题。能够将进入数据库的组件换成使用基于文件的持久性的组件而无需更改代码行,这真是太棒了(配置更改已完成)。
一旦我们使用了泛型,它就会变得更好。想象一下,有一个消息发布者可以接收记录并发布消息。它不在乎它发布什么,但是它需要一个映射器来从记录到消息中获取内容。
public class MessagePublisher<RECORD,MESSAGE> { public MessagePublisher(IMapper<RECORD,MESSAGE> mapper,IRemoteEndpoint endPointToSendTo) { //setup } }
我曾经写过它,但是现在,如果我发布不同类型的消息,则可以将许多类型注入到这组代码中。我还可以编写记录相同类型记录并将其映射到不同消息的映射器。将DI与Generics结合使用使我能够编写很少的代码来完成许多任务。
哦,是的,有一些可测试性问题,但是它们仅次于IoC / DI的好处。
我绝对喜欢IoC / DI。
- 当我们拥有一个稍微复杂一些的中型项目时,它就变得更加合适。我想说,当我们开始感到疼痛的那一刻就变得合适了。
回答
例如,任务1是创建对象。
没有IOC概念,任务#1应该由Programmer完成,但是有IOC概念,任务#1将由容器完成。
简而言之,控制权从程序员转换为容器。因此,这称为控制反转。
我在这里找到了一个很好的例子。
回答
在使用Inversion of Control之前,我们应该充分了解它有其优点和缺点的事实,并且应该知道为什么要使用它。
优点:
- 代码被解耦,因此我们可以轻松地将接口的实现与其他实现互换
- 它是针对接口而非实现进行编码的强大动力
- 为代码编写单元测试非常容易,因为它只依赖于其构造函数/设置器中接受的对象,并且可以轻松地使用正确的对象进行初始化。
缺点:
- IoC不仅会颠倒程序中的控制流,还会使程序变得相当模糊。这意味着我们不再只能阅读代码并从一个地方跳到另一个地方,因为通常在代码中存在的连接不再在代码中。而是在XML配置文件或者注释中以及在解释这些元数据的IoC容器的代码中。
- 出现了新一类的错误,我们会错误地配置XML或者注释,并且我们可能会花费大量时间找出为什么IoC容器在特定条件下将空引用注入到一个对象中的原因。
我个人看到了IoC的优点,我真的很喜欢它们,但是我倾向于尽可能避免使用IoC,因为它将软件变成一个类的集合,这些类不再构成"真正的"程序,而只是需要将它们组合在一起XML配置或者注释元数据,如果没有它,它会崩溃(或者崩溃)。
回答
什么是控制反转?
如果遵循以下两个简单步骤,就可以完成控制反转:
- 将要做的部分与何时做的部分分开。
- 确保何时对零件了解得越少越好;反之亦然。
根据用于实现的技术/语言,这些步骤中的每一种都有几种技术。
--
控制反转(IoC)的反转部分令人困惑。因为反转是相对项。理解IoC的最好方法就是忘记这个词!
--
例子
- 事件处理。事件处理程序(要做的部分)-引发事件(要做的部分)
- 接口。组件客户端(待办事项)-组件接口实现(待办事项)
- xUnit固定。 Setup和TearDown(要做的部分)-xUnit框架在开始时调用Setup,在结束时调用TearDown(当做部分)
- 模板方法设计模式。模板方法何时做部分-基本子类实现要做部分
- COM中的DLL容器方法。 DllMain,DllCanUnload等(待办事项)-COM / OS(待办事项)