依赖倒置原则

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

是指程序要依赖于抽象接口,不要依赖于具体实现。简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合。
包含三层含义:
1.模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生的;
2.接口或者抽象类不依赖于实现类;
3.实现类依赖接口或者抽象类。

实践

现在通过一个例子来说明,如下司机驾驶奔驰车的类图

司机与奔驰车的类图

代码如下:

public class Driver {
//司机的主要职责就是驾驶汽车
   public void drive(Benz benz) {
    benz.run();
  }
}

public class Benz {
//汽车肯定会跑
  public void run()  {
    System.out.println("奔驰汽车开始运行...");
  }
}

public class Client {
  public static void main(String[] args) {
    Driver liSi= new Driver();
    Benz benz = new Benz();
    //李四开奔驰车
    liSi.drive(benz);
    }
}

那么现在如果司机要去开宝马车了怎么办?按现在这个设计,司机只能开奔驰车而不能开宝马车,这个是有问题的,毕竟都是C1驾驶证却只能开奔驰车是不正确的。

现在引入依赖倒置原则,修改类图:

引入依赖倒置原则后的类图

代码如下:

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

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

public interface ICar {
  //是汽车就应该能跑
  public void run();
}
public class Benz implements ICar{
//汽车肯定会跑
  public void run(){
    System.out.println("奔驰汽车开始运行...");
  }
}
public class BMW implements ICar{
//宝马车当然也可以开动了
  public void run(){
    System.out.println("宝马汽车开始运行...");
  }
}
public class Client {
    public static void main(String[] args) {
    IDriver liSi= new Driver();
    ICar benz = new Benz();
    //李四开奔驰车
    liSi.drive(benz);
  }
}

这就是依赖倒置原则,在未修改之前,Driver是依赖Benz的,司机开什么车就去依赖什么车,这是“依赖正置”,现在倒置过来,Driver去依赖车的抽象接口ICar的,不管什么车都实现ICar,那么司机也就可以开任何的车,所以称为依赖倒置。

总结

依赖倒置原则的本质就是通过抽象(接口或者抽象类)使各个类或模块的具体实现彼此独立,互不影响,实现模块之间的松耦合,我们应该遵循以下几个规则:
1.每个类尽量都有接口或抽象类,或者两者都有。
2.变量的表面类型尽量是接口或者是抽象类。
3.任何类都不应该从具体类派生。
4.尽量不要覆写基类的方法。
5.结合里氏替换原则使用

推荐阅读更多精彩内容