🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## 英文名称(Dependence Inversion Principle ,DIP) **定义**:高层模块不应该依赖低层模块,应该依赖其抽象,抽象不应该依赖其细节,细节应该依赖其抽象。 **这句话在java中的理解**: 低层模块:具体细化的java类 高层模块:是由多个低层模块组成的。 抽象:指的是接口或者抽象类 依赖:存在类A的一个方法S,S传入的参数是另一个类B的实例,那么类A依赖于类B 我的理解---在项目开发中尽量将相同模块细化,类与类之间减少依赖关系,应该依赖其抽象类或者接口。 一个反面的例子: ----一个司机开宝马车。 按照常规的思维:定义一个司机类(Driver)有个void drive(BMW bmw)方法。该方法需要传入宝马车实例, 定义一个宝马车类(BMW) 有一个run方法。 ![](https://box.kancloud.cn/2016-06-06_57553406bfba4.jpg) ~~~ public class DIPTest { public static void main(String[] args) { new Driver().drive(new BMW()); } } class Driver{ public void drive(BMW bmw){ System.out.println("司机开车..."); bmw.run(); } } class BMW{ public void run(){ System.out.println("宝马车开动了...."); } } ~~~ **更改需求**,司机现在改开奔驰了,那么如果在这个类的基础上更改,我们需要给司机提供一个drive(Benz b)的方法。 同时再提供一个Benz类,提供一个run方法。那么就存在类之间的依赖性太大,不利于类的拓展。 **----解决方案**: 让细节类依赖其抽象,宝马车、奔驰车都具有run()方法,司机都具有drive(Car car)的方法。可以将共同的方法和类抽象成接口。 这样设计的好处,可以将司机和车分为两个模块进行开发,两者之间的依赖关系存在于接口,而具体实现类依赖于接口。这样在分工协作时,只需要各自定义好接口的操作方法就可以了。并且类的扩展性也大大提高。 ![](https://box.kancloud.cn/2016-06-06_57553406dcb84.jpg) ~~~ package hpu.lzl.dip; public class DIPTest2 { public static void main(String[] args) { IDriver d = new Driver2(); ICar ic = new BenzCar(); d.Driver(ic); System.out.println("----------------"); d.Driver(new BMWCar()); } } interface IDriver{ public void Driver(ICar car); } interface ICar{ public void run(); } class Driver2 implements IDriver{ @Override public void Driver(ICar car) { System.out.println("司机开车....."); car.run(); } } class BMWCar implements ICar{ @Override public void run() { System.out.println("宝马车开动了...."); } } class BenzCar implements ICar{ @Override public void run() { System.out.println("奔驰车开动了...."); } } ~~~ 依赖的三种写法 ## 1、构造函数传递依赖 ~~~ interface IDriver{ public void drive(); } class Driver2 implements IDriver{ private ICar car; public Driver2(ICar car){ this.car = car; } @Override public void drive() { System.out.println("司机发动车了..."); car.run(); } } ~~~ ## 2、setter方法传递依赖 ~~~ interface IDriver{ public void drive(); public void setCar(ICar car); } class Driver2 implements IDriver{ private ICar car; @Override public void drive() { System.out.println("司机开车....."); car.run(); } @Override public void setCar(ICar car) { // TODO Auto-generated method stub this.car = car; } } ~~~ ## 3、接口传递依赖 ~~~ interface IDriver{ public void drive(ICar car); } class Driver2 implements IDriver{ @Override public void drive(ICar car) { System.out.println("司机发动车了..."); car.run(); } } ~~~ **我对依赖倒置的理解** 依赖倒置首先要求类之间具有联系,将其联系抽象成接口或者抽象类,这样降低类之间的依赖。从而产生抽象类或接口之间的依赖,将具体事物时间的依赖转化成抽象接口的依赖。