依赖倒置原则
原始定义:
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语言中的表现是:
- 模块间的依赖通过抽象产生,类与类之间不直接耦合。
- 接口或抽象类不依赖于实现类,实现类依赖于接口或抽象。
依赖倒置原则更确切的说就是 面向接口编程
其优点是可以降低类之间的耦合,提高系统稳定性,同时提高了代码的可维护性和可读性。
在JavaBean,EJB等组件的设计中都使用了这一重要原则。
下面举一个列子说明:
定义一个Person类,拥有一个静态方法drive,可以驾驶奔驰车。
public class Person{
public void main(String []args)
{
drive(new Benz());
}
public static void drive(Benz benz)
{
benz.run();
}
}
class Benz{
public void run(){
System.out.println("Benz开车啦");
}
}
运行结果:Benz开车啦
假如有一天Person想开BMW,那必须要修改Person类,假如以后又想开丰田,大众,福特了呢?
这里就出现问题了,Person类与Benz类直接耦合不利于程序拓展。
在这里汽车是抽象,汽车类的run方法是细节,Person类是高层模块。应该让Person类和run方法依赖于抽象——汽车。
在这里引入抽象:汽车接口
public interface Car
{
public void run();//汽车都会跑
}
引入了汽车接口后的完整代码
public class Person{
public static void main(String []args)
{
drive(new Benz());
dirve(new BMW());
}
public static void drive(Car car)
{
car.run();
}
}
class Benz implements Car{//实现汽车接口
@Override
public void run()
{
System.out.println("Benz开车啦");
}
}
class BMW implements Car{//实现汽车接口
{
@Override
public void run(){
System.out.println("BMW开车啦");
}
}
运行结果:
Benz开车啦
宝马开车啦