分类: Java
2014-05-07 16:26:52
原文地址:依赖倒置、控制反转和依赖注入 作者:权镜士
依赖和耦合(dependency and coupling)
点击(此处)折叠或打开
点击(此处)折叠或打开
点击(此处)折叠或打开
Rose中定义“依赖”:依赖描述了两个模型元素之间的关系。如果被依赖的模型元素发生变化就会影响到另一个模型元素。
Martin Fowler描述“耦合”:如果改变程序的一个模块要求另一个模块同时发生变化,就认为这两个模块发生了耦合。
可看出:如果模块A调用模块B提供的方法,或者访问模块B中的某些数据成员(在OO中是不提倡这样做的),我们就认为模块A依赖于模块B,模块A和模块B之间发生了耦合。
究竟需不需要耦合?
如果所有模块之间都没有任何耦合关系,其结果必然是:整个软件不过是多个互不相干的系统的简单堆积,对这个系统而言,所有功能还是要做一个模块中实现,这等于是没有做任何模块的分解。
所以,永远不要幻想消除所有的依赖。要控制和消除不必要的耦合.
接口和实现分离(separation of interface and implementation )
特点:
1.应用程序调用类库,依赖于类库
2.接口和实现的分离从一定的程度上消解了这个依赖关系,具体的实现可以在编译期间发生变化,但是,这种消解方法的作用非常有限.
3.类库可以单独重用,但是应用程序不能脱离类库而重用,除非提供了一个实现了相同接口的类库。
A.上层模块不应该依赖于下层模块,它们共同依赖于一个抽象
B.抽象不能依赖于具体,具体依赖于抽象
含义:为了消解两个模块之间的依赖关系,应该在两个模块之间定义一个抽象接口,上层模块调用定义的函数,下层模块实现该接口。
特点:
1.应用程序调用类库的抽象接口,依赖于类库的抽象接口;具体的实现类派生自类库的抽象接口,也依赖于类库的抽象接口
2.应用程序和具体的类库实现完全独立,相互之间没有直接的依赖关系。只要保持接口类的稳定,应用程序和类库的具体实现都可以独立的发生变化
3.类库完全可以独立重用,应用程序和任何一个实现了相同抽象接口的类库协同工作。
用于消除框架和类库之间的依赖关系
框架和类库最重要的区别是:框架是一个“半成品”的应用程序,而类库只包含了一系列可被应用程序调用的类。
在面向对象领域,“回调函数”的替代物就是“模板方法模式”,也就是“好莱坞原则”(不要调用我们,让我们调用你)。
应用程序和框架系统之间的依赖关系的特点:
1.应用程序和框架系统之间实际上是双向调用,双向依赖的关系
2.依赖倒置原则可以减弱应用程序到框架之间的依赖关系
3.“控制反转”及具体的模板方法模式可以消解框架到应用程序之间的依赖关系,这也是所有框架系统的基础
4.框架系统可以独立重用
依赖注入(dependency injection)
1.抽象接口隔离了使用者和实现者之间的依赖关系,但创建具体实现类的实现对象仍会造成对于具体实现的依赖。
2.采用依赖注入可以消除这种创建依赖性,使用依赖注入后,某些类完全是基于抽象接口编写而成的,这可以最大限度的适应需求的变化
分离接口和实现是人们有效的控制依赖关系的最初尝试,而纯粹的抽象接口更好的隔离了互相依赖的两个模块,“依赖倒置”和“控制反转”原则从不同的角度描述了利用抽象接口消除耦合的动机。设计模式正是这一动机的完美体现。依赖注入模式可以把具体类的创建过程集中到合适的位置,这一动机和创建型模式有相似之处。
ps:原文中的例子是画图的,这里不太好贴图,就写成代码了,顺便也可以复习一下OO的一些概念