什么是依赖倒置原则?
依赖倒置原则(Dependence Inversion Principle,DIP)指设计代码结构时,高层模块不应该依赖底层模块,二者都应该依赖其抽象。抽象不应该依赖细节,细节应该依赖抽象。
依赖倒置原则作用
- 降低类与类之间的耦合性
- 提高系统的稳定性
- 提高代码的可读性和可维护性
- 降低修改程序带来的风险
案例分析
比如小明是一个代驾司机,有C照,就能驾驶奔驰汽车,那么汽车肯定是能运行的,我们来看下设计思路:
1、首先奔驰车在运行,所以需要定义一个运行汽车的方法
2、小明是一个代驾司机,所以需要定义个司机类,用于驾驶汽车
3、我们已经定义了司机类和奔驰类,那么就可用通过司机去驾驶奔驰车了
方案一:初始设计
1、奔驰汽车类
定义奔驰汽车类,有一个运行汽车的方法
1
2
3
4
5
class Benz {
void run() {
print("奔驰车开始运行");
}
}
2、代驾司机类
定义代驾司机类,让司机可以驾驶奔驰,所以代驾司机类依赖于奔驰汽车类
1
2
3
4
5
class Driver {
void drive(Benz benz) {
benz.run();
}
}
3、运行汽车
代驾司机运行奔驰汽车
1
2
3
4
5
6
void main(List<String> args) {
Driver driver = Driver();
driver.drive(Benz());
}
4、运行结果
1
2
3
Connecting to VM Service at http://127.0.0.1:50355/iUlmB09xyMc=/
奔驰车开始运行
Exited
5、完整代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void main(List<String> args) {
Driver driver = Driver();
driver.drive(Benz());
}
class Benz {
void run() {
print("奔驰车开始运行");
}
}
class Driver {
void drive(Benz benz) {
benz.run();
}
}
6、分析
上面代码实现了需求,运行也没有什么问题,但是代驾司机可不止会开奔驰,还会开宝马、奥迪等汽车,而这个时候代驾司机类把奔驰通过形参的方式写死传入,耦合度非常高,修改起来的话成本也非常大,我们来看下如果优化
方案二:设计优化方案—接口抽象
在方案一中因为模块之间的相互依赖,违背了依赖倒置原则,使得项目的耦合性非常高。吸取经验,我们通过接口抽象的方式就可以很好的解决方案一中碰到的问题
1、汽车接口类
定义一个汽车接口类,有一个运行方法
1
2
3
abstract class ICar {
void run();
}
2、奔驰、奥迪车实现类
奔驰、奥迪车通过实现接口的方式重写run方法,去实现对应的运行逻辑
1
2
3
4
5
6
7
8
9
10
11
12
13
class Benz implements ICar {
@override
void run() {
print("奔驰车开始运行");
}
}
class Audi implements ICar {
@override
void run() {
print("奥迪开始运行");
}
}
3、代驾司机接口类
定义代驾司机接口类,形参是通过传入汽车接口类
1
2
3
abstract class IDriver {
void drive(ICar car);
}
4、代驾司机实现类
代驾司机通过实现可根据汽车的不同去驾驶不同种类的汽车
1
2
3
4
5
6
class Driver implements IDriver {
@override
void drive(ICar car) {
car.run();
}
}
5、运行汽车
1
2
3
4
5
void main(List<String> args) {
Driver driver = Driver();
driver.drive(Benz());
driver.drive(Audi());
}
6、运行结果
1
2
3
4
Connecting to VM Service at http://127.0.0.1:51512/6QojwIpD-iA=/
奔驰车开始运行
奥迪开始运行
Exited
7、完整代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
void main(List<String> args) {
Driver driver = Driver();
driver.drive(Benz());
driver.drive(Audi());
}
abstract class ICar {
void run();
}
class Benz implements ICar {
@override
void run() {
print("奔驰车开始运行");
}
}
class Audi implements ICar {
@override
void run() {
print("奥迪开始运行");
}
}
abstract class IDriver {
void drive(ICar car);
}
class Driver implements IDriver {
@override
void drive(ICar car) {
car.run();
}
}
8、分析
我们通过接口抽象的方式让司机类和汽车类进行解耦,不管以后新增什么车型,司机都能轻松驾驭,而且不需要修改原有代码,有效的提供系统稳定性。
总结
依赖倒置原则主要作用于降低耦合性、提升稳定性、提高代码可读性和可维护性。