面向对象六大原则(四):依赖倒置原则

时间:2022-03-31 17:23:12
一、概述

依赖倒置原则( Dependence Inversion  Principle ,缩写:DIP),是程序要依赖于抽象接口,不要依赖于具体实现。简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合。

二、原则

1.高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象。

2.抽象不应该依赖于具体实现,具体实现应该依赖于抽象。

三、实现方法

下面引用一个简单示例:
    //抽象汽车
public interface ICar {
void Run();
void Turn();
void Stop();
}

//抽象的具体实现
public class BmwCar implements ICar {
@Override
public void Run() {
System.out.print("宝马开始启动了");
}

@Override
public void Turn() {
System.out.print("宝马转弯了");
}

@Override
public void Stop() {
System.out.print("宝马停了");
}
}

//抽象的具体实现
public class FllCar implements ICar {
@Override
public void Run() {
System.out.print("法拉利开始启动了");
}

@Override
public void Turn() {
System.out.print("法拉利转弯了");
}

@Override
public void Stop() {
System.out.print("法拉利停了");
}
}

public class AutoSystem {
private ICar icar;

//依赖于抽象ICar
public AutoSystem(ICar icar) {
this.icar = icar;
}

private void RunCar() {
icar.Run();
}

private void TurnCar() {
icar.Turn();
}

private void StopCar() {
icar.Stop();
}
}

现在AutoSystem系统依赖于ICar这个抽象,而与具体的实现细节BmwCar、FllCar无关,所以实现细节的变化不会影响AutoSystem。对于实现细节只要实现ICar即可,即实现细节依赖于ICar抽象。

从我的另一篇博客  “面向对象六大原则(二):开闭原则” 的示例代码中也是同样的道理,我们建立了ImageCache抽象,并且让ImageLoader依赖于抽象而不是具体细节。当需求发生变化时,只需要实现ImageCache类或者继承其他已有的ImageCache子类完成相应的缓存功能,然后将具体的实现注入到ImageLoader即可实现缓存功能的替换,这就保证了缓存系统的高可扩展性,有了拥抱变化的能力,这就是依赖倒置原则。

四、分析
     
在java中,抽象就是指 “接口”或“抽象”类,两者都是不能直接被实例化;细节就是实现类,实现接口或继承抽象类而产生的类就是细节,其特点就是可以直接被(new)实例化。高层模块就是调用端,低层模块就是具体实现类。

在java中表现为:模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生的。