只依赖于抽象,这就能帮助我们实现松耦合,使得设计易于修改,DIP允许测试 数据库细节能够如插件一样插入我们的系统。
1、高层模块不要依赖低层模块
2、高层和低层模块都要依赖于抽象
3、抽象不要依赖于具体实现
4、具体实现要依赖于抽象
5、抽象和接口使模块之间的依赖分离。
例如我们经常会用到宏观的一种体系结构模式--layer模式,通过层的概念分解和架构系统,比如常见得三层架构等。那么依赖关系应该是自上而下,也就是上层模块依赖于下层模块,而下层模块不依赖于上层,如下图所示。
这应该还是比较容易理解的,因为越底层的模块相对就越稳定,改动也相对越少,而越上层跟需求耦合度越高,改动也会越频繁,所以自上而下的依赖关系使上层发生变更时,不会影响到下层,降低变更带来的风险,保证系统的稳定。
上面是立足在整体架构层的基础上的结果,再换个角度,从细节上再分析一下,这里我们暂时只关注UI和Service间的关系,如下面这样的依赖关系会有什么样的问题?
第一,当需要追加提供一种新的Service时,我们不得不对UI层进行改动,增加了额外的工作。
第二,这种改动可能会影响到UI,带来风险。
第三,改动后,UI层和Logic层都必须重新再做Unit testing。
那么具体怎么优化依赖关系才能让模块或层间的耦合更低呢?想想前面讲的OCP原则吧,观点是类似的。
我们可以为Service追加一个抽象层,上层UI不依赖于Service的details,UI和Service同时依赖于这个Service的抽象层。如下图是我们的改进后的结果。
这样改进后会有什么好处呢?
第一,Service进行扩展时,一般情况下不会影响到UI层,UI不需要改动。
第二,Service进行扩展时,UI层不需要再做Unit testing。
总结:
这几条原则是非常基础而且重要的面向对象设计原则。正是由于这些原则的基础性,理解、融汇贯通这些原则需要不少的经验和知识的积累。
1、一个对象只承担一种责任,所有服务接口只通过它来执行这种任务。
2、程序实体,比如类和对象,向扩展行为开放,向修改行为关闭。
3、子类应该可以用来替代它所继承的类。
4、一个类对另一个类的依赖应该限制在最小化的接口上。
5、依赖抽象层(接口),而不是具体类。
本文部分来源:http://blog.csdn.net/dxpqxb/article/details/51732555
备注:
层(layer)体系架构模式就是把应用系统分解成子任务组,其中每个子任务组处于一个特定的抽象层次上。
IOC(控制反转):全称为:Inverse of Control。从字面上理解就是控制反转了,将对在自身对象中的一个内置对象的控制反转,反转后不再由自己本身的对象进行控制这个内置对象的创建,而是由第三方系统去控制这个内置对象的创建。
DI(依赖注入):全称为Dependency Injection,意思自身对象中的内置对象是通过注入的方式进行创建。
IOC就是一种软件设计思想,DI是这种软件设计思想的一个实现。而Spring中的核心机制就是DI。