本文来了解一下什么是依赖倒置原则。

定义

  • 定义:高层模块不应该依赖底层模块,二者都应该依赖其抽象
  • 抽象不应该依赖细节,细节应该依赖抽象
  • 针对接口编程,不要针对实现编程
  • 优点:减少耦合性,提高稳定性

例子

比如我叫swg,我学习java的课程,也要学习前端的课程,如何写呢?

image

第一个版本-V1

最直接的,就是写一个类,里面写两个方法,一个学习java,一个学习前端:

1
2
3
4
5
6
7
8
9
public class StudyCourse {
public void studyJava(){
System.out.println("swg is studying java...");
}

public void studyFE(){
System.out.println("swg is studying fe...");
}
}

那么,调用就是:

1
2
3
4
5
6
7
public class Test {
public static void main(String[] args) {
StudyCourse studyCourse = new StudyCourse();
studyCourse.studyJava();
studyCourse.studyFE();
}
}

如果此时,我又要学python了,那么咋办呢?直接在studyCourse中再新增一个方法?

那么,就会违背依赖倒置原则,即高层模块不应该依赖于低层模块。也就是说,我不能面向实现编程。

第二个版本-V2

我们应该面向接口编程,达到高层与低层实现解耦的目的。首先定义一个课程接口,里面一个声明是study()

1
2
3
public interface ICourse {
void study();
}

那么,如果是java课,就是:

1
2
3
4
5
6
public class JavaCourse implements ICourse{
@Override
public void study() {
System.out.println("Swg is stydying java...");
}
}

如果是前端课就是:

1
2
3
4
5
6
public class FECourse implements ICourse{
@Override
public void study() {
System.out.println("Swg is stydying FE...");
}
}

任意的课程都可以取拓展。。。

那么,如何实现调用类,即高层与这些具体的实现类解耦呢?这里直接传入一个接口类型的参数进去,高层只要调用这个接口的某一种实现类即可。

1
2
3
4
5
6
public class Swg {

public void studyCourse(ICourse iCourse) {
iCourse.study();
}
}

调用:

1
2
3
4
5
6
7
8
public class Test {
public static void main(String[] args) {
Swg swg = new Swg();
swg.studyCourse(new JavaCourse());
swg.studyCourse(new FECourse());
//...
}
}

第三个版本-V3

上面是用参数传进去,我们还可以用构造函数的方式传入,主要是修改Swg:

1
2
3
4
5
6
7
8
9
10
public class Swg {
private ICourse iCourse;
public Swg(ICourse iCourse){
this.iCourse = iCourse;
}

public void study(){
iCourse.study();
}
}

调用:

1
2
3
4
5
6
7
8
public class Test {
public static void main(String[] args) {
Swg swg = new Swg(new JavaCourse());
swg.study();
swg = new Swg(new FECourse());
swg.study();
}
}

第四个版本-V4

我们还可以用set进行注入,具体为:

1
2
3
4
5
6
7
8
9
10
11
public class Swg {
private ICourse iCourse;

public void setiCourse(ICourse iCourse) {
this.iCourse = iCourse;
}

public void study(){
iCourse.study();
}
}