依赖倒置原则
依赖倒置原则(Dependency Inversion Principe,DIP)原始定义:
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,面向对象设计)的精髓之一。
采用依赖倒置原则可以减少类间的耦合性,提高系统的稳定性,降低并行开发引起风险,提高代码可读性和可维护性。
example:
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 drive(ICar car) {
System.out.println("Benz run ...");
}
}
public class BWM implements ICar {
public void drive(ICar car) {
System.out.println("BWM run ...");
}
}
/**
* 业务1
*/
public class Client {
public static void mian(String[] args) {
IDriver zhangSan = new Driver();
ICar benz = new Benz();
zhangSan.drive(benz);
}
}
/**
* 业务2
*/
public class Client {
public static void mian(String[] args) {
IDriver zhangSan = new Driver();
ICar bmw = new BMW();
zhangSan.drive(bmw);
}
}
依赖的三种写法
构造函数传递依赖对象
在类中通过构造函数声明依赖对象,按照依赖注入的说法,这种方法叫做构造函数注入。
public interface IDriver {
public void drive();
}
public class Driver implements IDriver {
private ICar car;
public Driver(ICar car) {
this.car = car;
}
public void drive() {
this.car.run();
}
}
Setter方法传递依赖对象
在抽象中设置Setter方法声明依赖关系,依照依赖注入的说法,这是Setter注入,按照这种方式注入。
public interface IDriver {
public void drive();
public void setCar(ICar car);
}
public class Driver implements IDriver {
private ICar car;
public viod setCar(ICar car) {
this.car = car;
}
public void drive(ICar car) {
this.car.run();
}
}
接口声明依赖注入
在接口方法中声明依赖对象,也叫作接口注入。
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 drive(ICar car) {
System.out.println("Benz run ...");
}
}
public class BWM implements ICar {
public void drive(ICar car) {
System.out.println("BWM run ...");
}
}
public class Client {
public static void mian(String[] args) {
IDriver zhangSan = new Driver();
ICar benz = new Benz();
zhangSan.drive(benz);
}
}