天天看点

设计模式六大原则之依赖倒置原则

1.       依赖倒置原则(Dependence Inversion Principle,DIP)

High level modules should not depend upon low level modules.Both should depend upon abstractions. Abstractions should not depend upon details should depend upon abstractions

翻译过来:

n         高层模块不应该依赖低层模块,两者都应该依赖其抽象。

n         抽象不应该依赖细节

n         细节应该依赖抽象

高层模块和低层模块容易理解,每一个逻辑的实现都是由原子逻辑组成的,不可分割的原子逻辑就是低层模块,原子逻辑的再组装就是高层模块。细节就是实现类,实现接口或继承抽象类而产生的类就是细节,其特点就是可以直接被实例化,也就是可以加上一个关键字new产生一个对象。

依赖倒置原则在java语言中的直接表现就是:

n         模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生的。

n         接口或抽象类不依赖于实现类;

n         实现类依赖接口或抽象类

更加精简的定义就是“面向接口编程”——OOD(Object-Oriented Design,面向对象设计)的精髓之一。

依赖倒置原则是建立在“契约”之上,采用依赖倒置原则可以减少类间的耦合性,提高系统稳定性,降低并行开发引起的风险,提高代码的可读性和可维护性。

证明定理是否正确由两种常用方法:

第一种:根据提出的论题,经过一番论证,推出和定理相同的结论,这是顺推证法;

另外一种就是:首先提出命题的伪命题,然后推导出一个荒谬,与已知条件互斥的结论,这是反证法。

如果不使用依赖倒置原则就会加重类间的耦合性,降低系统的稳定性,增加并行开发的风险,降低代码的可读性和可维护性。(并发风险:并行开发最大的风险就是风险扩散,本来只是一段程序的错误或异常,就逐步波及一个功能每一个模块,甚至到最后毁坏整个项目。)如果两个类之间有依赖关系,只要制定出两者之间的接口(或抽象类)就可以独立开发了,而且项目之间的单元测试也可以独立地运行,而TDD(Test-Driver Development,测试驱动开发)开发模式就是依赖倒置原则最高级的应用。(测试驱动开发,先写好单元测试类,然后再写实现类,这对提高代码的质量有非常大的帮助,特别适合研发类项目或项目成员整体水平比较低的情况下使用)

      抽象是对实现的约束,对依赖者而言,也是一种契约,不仅仅约束自己,还同时约束自己与外部的关系,其目的就是保证所有细节不脱离契约范畴,确保约束双方按照既定的契约(抽象)共同发展,只要抽象这根基线在,细节就脱离不了这个圈圈,始终让你对象做到“言必信,行必果”。

       依赖的三种写法:

   构造函数传递依赖对象

在类中通过构造函数声明依赖对象,按照依赖注入的说法,这种叫构造函数注入。

       Setter方法传递依赖对象

       在抽象中设置Setter方法声明依赖关系,依照依赖注入的说法,这是Setter依赖注入。

       接口声明依赖对象

       在接口的方法中声明依赖对象。

依赖倒置原则

1.         每个类尽量都由接口或抽象类,或抽象类和接口两者都具备(有依赖才有依赖倒置)。

接口和抽象类都是属于抽象的,有了抽象才可能依赖倒置。

2.         变量的表面类型尽量是接口或是抽象类

变量的类型通常是要接口或者抽象类。但是工具类例外,如果使用clone方法,就必须使用实现类,这是JDK提供一个规范。

3.         任何类都是、不应该从具体类派生

项目维护可以不考虑这个规则,维护工作基本就是扩展开发,修复行为,通过一个继承关系复写一个方法就可以修正一个很大的bug,何必要继承最高的基类。

4.         尽量不要复写基类的方法

如果基类是一个抽象类,而且这个方法已经实现了,子类尽量不要复写。类间依赖的是抽象,复写了抽象方法。对依赖的稳定性会造成一定的影响。

5.         结合里氏替换原则使用。

接口负责定义public 属性和方法,并且声明与其他对象的依赖关系,抽象类负责公共的构造步伐的实现,实现类准确的实现业务逻辑,同时在适当的时候对父类进行细化。

       依赖倒置就是类间的依赖是确确实实的实现类间的依赖,也就是我们说的面向对象编程。而编写程序需要的就是对现实世界的进行抽象,抽象的结果就是由了抽象类和接口。

这个原则在小项目中难以体现,通常用于比较大的项目,特别是规避一些非技术性因数引起的问题。如果设计优良,代码结构清晰,人员对项目的影响基本为零。采用依赖倒置可以让维护人员轻松地扩展和维护。