依赖注入(非原创 资料汇总)

1. 依赖注入与控制反转

控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。(来自维基百科)

2. 依赖注入定义:

来源:https://segmentfault.com/q/1010000002578931

依赖注入:程序运行过程中,如需另一个对象协作(调用它的方法、访问他的属性)时,无须在代码中创建被调用者,而是依赖于外部容器的注入

3. 名词解释:

依赖:一种模型元素之间的关系的描述。例如类A调用了类B,那么我们说类A依赖于类B。
耦合:一种模型元素之间的关系的描述。例如类A调用了类B或类B调用了类A,那么我们说类A与类B有耦合关系。
耦合度:模型元素之间的依赖程度的量化描述。
控制:一种模型元素之间的关系的描述。例如类A调用了类B,那么我们说类A控制类B。

4. 到底什么叫依赖注入?

来源:https://segmentfault.com/q/1010000002578931

举个栗子

一个人(Java实例,调用者)需要一把斧子(Java实例,被调用者)
在原始社会里,几乎没有社会分工;需要斧子的人(调用者)只能自己去磨一把斧子(被调用者);对应情形为:Java程序里的调用者自己创建被调用者,通常采用new关键字调用构造器创建一个被调用者
进入工业社会,工厂出现了,斧子不再由普通人完成,而在工厂里被生产出来,此时需要斧子的人(调用者)找到工厂,购买斧子,无须关心斧子的制造过程;对应简单工厂设计模式,调用者只需定位工厂,无须管理被调用者的具体实现
进入“共产主义”社会,需要斧子的人甚至无须定位工厂,“坐等”社会提供即可;调用者无须关心被调用者的实现,无须理会工厂,等待Spring依赖注入
总之依赖注入的意思是你需要的东西不是由你创建的,而是第三方,或者说容器提供给你的。这样的设计符合正交性,即所谓的松耦合。

5. 为什么要使用依赖注入?

传统应用程序通常是在类内部执行代码中主动创建这个类所依赖的其它对象,从而导致类与类之间发生紧密耦合,使得类难于测试和隔离,最终导致系统的扩展和维护异常困难。依赖注入用来解决组件之间依赖关系、配置及生命周期管理,通过转移对象控制权,可以解决类之间的耦合问题,对象与对象之间是松散耦合关系,更重要的是使得应用程序体系结构变得非常灵活,很好的体现了面向对象的设计法则之一—依赖设计原则,即著名的好莱坞原则:“Don’t call us, we’ll call you.(不要调用我们,我们会调用你)。

6. 依赖注入的几种方法

来自说说依赖注入

构造器注入
将需要的依赖作为构造方法的参数传递完成依赖注入。

class Car {
  Energy mEnergy;
  public Car(Energy energy) {
      mEnergy = energy;
  }
}

Setter方法注入
增加setter方法,参数为需要注入的依赖亦可完成依赖注入。

class Car {
  Energy mEnergy;

  public void setEnergy(Energy energy) {
      mEnergy  = energy;
  }
}

接口注入
接口注入,闻其名不言而喻,就是为依赖注入创建一套接口,依赖作为参数传入,通过调用统一的接口完成对具体实现的依赖注入。

interface EnergyConsumerInterface {
  public void setEnergy(Energy energy);
}

class Car implements EnergyConsumerInterface {
  Energy mEnergy;

  public void setEnergy(Energy energy) {
      mEnergy  = energy;
  }
}

接口注入和setter方法注入类似,不同的是接口注入使用了统一的方法来完成注入,而setter方法注入的方法名称相对比较随意。

7. Anjular.js中的依赖注入

来源:
https://checkcheckzz.gitbooks.io/angularjs-learning-notes/content/chapter4/chapter4.html

先看我们之前代码中的一处函数定义:

  var BoxCtrl = function($scope, $element){}

在这个函数定义中,注意那两个参数: $scope$element ,这是两个很有意思的东西。总的来说,它们是参数,这没什么可说的。但又不仅仅是参数——你换个名字代码就不能正常运行了。
事实上,这两个参数,除了完成“参数”的本身任务之外,还作为一种语法糖完成了“依赖声明”的任务。本来这个函数定义,完整的写法应该像 AMD 声明一样,写成:

var BoxCtrl = ['$scope', '$element', function(s, e){}];

这样就很明显,表示有一个函数,它依赖于两个东西,然后这两个东西会依次作为参数传入
简单起见,就写成了一个函数定义原本的样子,然后在定义参数的名字上作文章,来起到依赖声明的作用。
在处理时,通过函数对象的 toString() 方法可以知道这个函数定义代码的字符串表现形式,然后就知道它的参数是 $scope$element 。通过名字判断出这是两个外部依赖,然后就去获取资源,最后把资源作为参数,调用定义的函数。
所以,参数的名字是不能随便写的,这里也充分利用了 js 的特点来尽量做到“反省”了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值