依赖倒置原则(Dependence Inversion Principle)

xiaoxiao2021-02-28  104

原始定义        High level modules should not depend upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should depend upon abstractions. 三层含义:

高层模块不应该依赖底层模块,两者都依赖其抽象。抽象不依赖细节。细节应该依赖于抽象。

【注解】在Java语言中,抽象就是指接口或抽象类,两者都是不能直接被实例化的。细节就是具体的实现类,实现类实现了接口或继承了抽象类,其特点是可以直接被实例化。依赖倒置原则在Java语言中的表现是:

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

依赖倒置原则更加精确的定义就是“面向接口的编程”——OOD(Object-Oriented Design)的精髓之一。其是JavaBean、EJB和COM等组件设计模型背后的基本原则。 示例        在现实生活中,司机只要会开车,就可以开奔驰车,也可以开宝马车。因此司机不依赖于奔驰或宝马车,而是通过如下图所示的接口,使他们之间的依赖关系倒置。        司机接口只是一个抽象的概念,是对司机这类事物的抽象,只要是司机都有一个共同的行为——开车,因此,在IDriver接口中使用drive()方法进行抽象。接口IDriver源代码如下:

public interface IDriver { //司机都会驾驶汽车 public void drive(ICar car); }

       司机类Driver实现IDriver接口,Driver源代码如下:

public class Driver implements IDriver { //司机的主要职责是驾驶 @Override public void drive(ICar car) { car.run(); } }

       汽车接口ICar的源代码如下:

public interface ICar { //汽车都能跑 public void run(); }

       奔驰汽车类Benz实现ICar接口,源代码如下:

public class Benz implements ICar { @Override public void run() { System.out.println("奔驰汽车在行使..."); } }

       宝马汽车类BMW也实现ICar接口,源代码如下:

public class BMW implements ICar { @Override public void run() { System.out.print("宝马汽车在行使..."); } }

       测试类Test,源代码如下:

public class Test { public static void main(String[] args) { //实例化一个司机 IDriver tom = new Driver(); //实例化一辆宝马车 ICar car = new BMW(); //tom开车 tom.drive(car); } }

【注解】这程序看起来就非常的6了,虽然规模很小,当司机tom想开奔驰车时,只需将“new BMW()”改为“new Benz()”即可,更改会引起的风险很小。这样的原则果然乃出自大牛之作,相比大家也迫不及待地想学习使用了,不过先别急,我们还需要弄懂一件事,那就是它适用的场景,有什么优点?        依赖倒置原则在小型项目中很难体现出来。在大中型项目中,采用依赖倒置原则具有非常多的优点,特别是它能规避一些非技术原因引起的问题。项目越大,需求变化的概率也越大,采用依赖倒置原则可以使接口或抽象类对实现类进行约束,从而减少需求变化引起的工作量剧增的情况。人员的变动在大中型项目中也是时常存在的,如果程序设计优良、代码结构清晰时,人员变化对项目的影响就会很小。同时,它是实现开闭原则的重要途径,依赖倒置原则没有实现,就不能实现对扩展的开放,对修改关闭。        在项目中使用这个原则需要遵循以下几个规则:

每个类应该都具有接口或抽象类,或者同时具备抽象类和接口。变量的表面类型(表面类型是在定义的时候赋予的类型,实际类型是创建时对象的类型,例如tom表面类型是IDriver,实际类型是Driver)尽量是接口或者是抽象类。任何类都不应该从具体类派生。尽量不要重写基类的方法。如果基类是一个抽象类,并且其方法已经实现了,子类尽量不要重写。结合里氏替换原则。里氏替换原则指出父类出现的地方子类就可以出现,结合依赖倒置原则可以得出一个通俗的规则:接口负责定义抽象方法,并且声明与其他对象的依赖关系;抽象类负责公共构造部分的实现,实现类准确地实现业务逻辑,同时在适当的时候对父类进行细化。
转载请注明原文地址: https://www.6miu.com/read-79496.html

最新回复(0)