深入理解依赖倒置原则

何为依赖导致原则?

Robert C. Martin在他的著作《敏捷软件开发:原则、模式与实践》中有这样的两句描述

1.High-level modules should not depend onlow-level modules. Both should depend on abstractions.(高层模块不应该依赖于低层模块,二者都应该依赖于抽象)

2.Abstractions should not depend upondetails. Details should depend upon abstractions.(抽象不应该依赖于具体实现细节,而具体实现细节应该依赖于抽象)

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

其核心思想是:要面向接口编程,不要面向实现编程。

基本概念

抽象与细节

在Java中,抽象就是指接口或者抽象类,两者都是不能直接被实例化的;细节就是实现类,实现接口或者继承抽象类而产生的就是细节,以关键字new产生对象。

高层与低层

通俗来讲高层模块就是调用端,低层模块就是具体实现类。

具体实现

先看下不符合依赖导致原则会产生什么后果。

比如一个司机开奔驰车:

public class Driver{

  public void drive(Benz benz){

    benz.run();

  }

}

public class Benz{

  public void run(){

    System.out.println("奔驰开始运行...")

  }

}

public class Test{
  public static void main(Sting[] args){
    Driver zhangsan = new Driver();

    Benz benz = new Benz();

    zhangsan.drive(benz);
  }
}
这样zhangsan 就可以开奔驰了,但是如果zhangsan明天要开宝马的车呢?

public class BMW{

  public void run(){

    System.out.println("宝马车开始运行...."); 

  } 

}

他不能开,因为张三没有开宝马车的方法,除非要改driver类的方法。张三作为一个司机,居然没法开别的品牌的车,这不符合常理。

下面引入了依赖倒置原则

创建司机接口

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 zhangsan = new Driver();
    ICar benz = new Benz();
    ICar bmw = new BMW();


    zhangsan.drive(benz);

    zhangSan.drive(bmw);
  }
}

这样就实现了司机可以开任何品牌的汽车,添加新的品牌不需要修改司机类。

依赖倒置是指导代码解耦的一个原则,通过增加一个抽象层来解耦低层和高层。

参考链接

https://cloud.tencent.com/developer/news/17567

https://blog.csdn.net/u013862108/article/details/79054620

posted @ 2020-03-20 23:16  涤生-  阅读(2764)  评论(0编辑  收藏  举报