控制反转和依赖注入原理

1.    IoC与DI基本概念

  •  "控制反转"本身是一个大而泛的概念,控制反转"普遍存在,比如事件处理模型、各种类型的接口回调等等,Martin Fowler根据"控制的哪一方面被反转了"这样的原则,把Spring为代表的框架所实现的"控制反转"称之为"依赖注入"。它们的共性是,均反转了"如何定位依赖的具体实现"。
  • 依赖注入具体可以细分为三种形式:构造方法注入、设值注入、接口注入。

2.    依赖注入的三种形式

  • 构造函数注入的原理是:把类所依赖的所有引用都通过构造函数的参数进行声明,这样,在构造对象的同时便获得了所有的依赖关系。
  • 设值注入的原理是:所有的依赖关系都提供相应的Setter方法,由外部调用相应的Setter方法完成各依赖关系的注入。
  • 接口注入的原理是:被依赖的关系抽象成接口,依赖的主动方需要实现相应的接口,通过调用接口方法完成注入。它的原理和设值注入有些类似。

3.    服务定位器模式

  • 服务定位器(Service Locator)模式并不是IoC的一种实现,因为它并没有实现什么"反转"。
  • 服务定位器模式背后的基本思想是:有一个对象(即服务定位器)知道如何获得一个应用程序所需的所有服务。

4.    服务定位器和依赖注入的选择

  • 这两个模式都提供了基本的解耦合能力——无论使用哪个模式,应用程序代码都不依赖于服务接口的具体实现。两者之间最重要的区别在于,这个"具体实现"以什么方式提供给应用程序代码。使用服务定位器模式时,应用程序代码直接向服务定位器发送一个消息,明确要求服务的实现;使用依赖注入模式时,应用程序代码不发出显式的请求,服务的实现自然会出现在应用程序代码中,这也就是所谓"控制反转"。
  • 使用服务定位器模式时,服务的使用者必须依赖于服务定位器。定位器可以隐藏使用者对服务具体实现的依赖,但你必须首先看到定位器本身。所以,选择服务定位器还是依赖注入,取决于"对定位器的依赖"是否会给你带来麻烦。
  • 依赖注入模式可以帮助你看清组件之间的依赖关系:你只需观察依赖注入的机制,就可以掌握整个依赖关系。而使用服务定位器模式时,你就必须在源代码中到处搜索对服务定位器的调用。
  • Martin Fowler指出,使用DI增加了代码的理解和调试难度,能不使用DI则尽量不要使用,可以使用更直观的服务定位器来实现解耦。但是该观点发表于2004年,目前依赖注入的思想深入人心,理解难度已基本不存在;同时DI框架已经非常成熟,调试、测试都有很方便的辅助工具。

5.    构造方法注入和设值注入的选择

  • 和设值注入、服务定位器模式相比,接口注入没有任何优势,因此基本不做考虑。
  • 构造方法注入一个好处是,你可以隐藏任何不可变的字段,只要不为它提供设值方法就行了。如果你通过设值方法完成初始化,暴露出来的设值方法很可能成为你心头永远的痛。但是如果参数太多,构造方法会显得凌乱不堪。
  • Martin Fowler建议优先考虑使用构造方法注入,在构造方法注入不太合适的场合再考虑设值注入。
posted @ 2015-11-22 20:39  CN.SnailRun  阅读(859)  评论(0编辑  收藏  举报