所谓依赖倒置原则(Dependence Inversion Principle)就是要依赖于抽象,不要依赖于具体。简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合,并由此引申出IoC、DI以及Ioc容器等概念。
面向过程的开发,上层调用下层,上层依赖于下层,当下层剧烈变动时上层也要跟着变动,这就会导致模块的复用性降低而且大大提高了开发的成本。
面向对象的开发很好的解决了这个问题,一般情况下抽象的变化概率很小,让用户程序依赖于抽象,实现的细节也依赖于抽象。即使实现细节不断变动,只要抽象不变,客户程序就不需要变化。这大大降低了客户程序与实现细节的耦合度。
依赖倒置原则(DIP):一种软件架构设计的原则(抽象概念)。
控制反转(IoC):一种反转流、依赖和接口的方式(DIP的具体实现方式)。
依赖注入(DI):IoC的一种实现方式,用来反转依赖(IoC的具体实现方式)。
IoC容器:依赖注入的框架,用来映射依赖,管理对象创建和生存周期(DI框架)。
高层模块不依赖于底层模块,而底层模块依赖于高层模块的接口(高层模块定义接口,底层模块负责实现)。
高层模块(接口):抽象 底层模块(实现接口):实现 ==>两者应该依赖于抽象,抽象(高层)不依赖实现(底层),实现(底层)依赖于抽象(高层)。
再来举个例子:
1、如果依赖不导致将会出现:高层模块依赖于底层模块,也就是说底层变成了抽象,高层需要实现抽象出来的所有接口,一旦底层出现新的模块,则就需要去修改高层的模块,破坏了开放-封闭原则。
2、如果依赖倒置将会出现:底层模块依赖于高层模块,也就是说高层变成了抽象,底层只需要去实现高层的接口就行,一旦底层出现新的模块,则高层模块就不需要去修改(定义抽象接口不变)。
由此可见DIP的优点:
系统更柔韧:可以修改一部分代码而不影响其他模块。
系统更健壮:可以修改一部分代码而不会让系统崩溃。
系统更高效:组件松耦合,且可复用,提高开发效率。
接下来说下"控制反转(Ioc)":
DIP是一种软件设计原则,是告诉我们模块之间应该是怎样的一种关系,那Ioc就是具体的一种软件设计模式,告诉我们应该如何去做,才能做到程序间的解耦。
Ioc(控制反转)为高、低层模块之间提供了抽象,也就是第三方系统,也就是依赖对象(底层对象)不在依赖的模块中(高层模块)中直接创建对象,而是把创建对象的权利交给第三次Ioc容器来创建,然后再把对象交给依赖模块(联想刚刚取钱的例子,ATM机器是高层模块,它自身并没有决定要插入哪个银行的银行卡,比如建行,农行,要插入什么卡的决定权在于我们(也就是第三方),我们插入什么行的卡,它就给我们什么银行的服务)。
传递注入的方式有三种:
1、构造注入:顾名思义利用构造方法注入
2、setter方法注入:在需要注入的类里提供一个setter方法
3、接口注入:因为具有代码侵入性,一般很少用,前2种居多
因此Ioc容器就这样诞生了,也就是DI的一个框架,用来简化我们的操作,Ioc容器可以做到动态创建、注入对象,对象的生命周期管理,映射依赖关系等。
Ioc容器有很多比如:PicoContainer,JBoss Microcontainer,Soto,Spring等。
总结一下:
DIP是软件设计的一种思想,IoC则是基于DIP衍生出的一种软件设计模式。
DI是IoC的具体实现方式之一,使用最为广泛。
IoC容器是DI注入的框架,它管理着依赖项的生命周期以及映射关系。
http://www.cnblogs.com/lichenwei/p/3943960.html