依赖倒置原则
# 依赖倒置原则(Dependence Inversion Principle)
定义:高层模块不应该依赖底层模块,两者都应该依赖其抽象部分,而抽象不能依赖于细节,但是细节需要依赖抽象。
**针对接口编程而不是针对具体的实现编程;**
优点:可以减少类之间的耦合关系,提高系统的稳定性,同时也提高代码的可读性和可维护性,降低修改程序所造成的风险。
## Tom
```java
public class Tom {
public void studyJava(){
System.err.println("Tom study Java");
}
public void studyPython(){
System.err.println("Tom study Python");
}
public void studyCPlusPlus(){
System.err.println("Tom study CPlusPlus");
}
}
```
## TomMain 测试类
```text
public class TomMain {
public static void main(String[] args) {
Tom tom = new Tom();
tom.studyCPlusPlus();
tom.studyJava();
tom.studyPython();
}
}
```
TomMain调用Tom方法,TomMain相当于是上层,而Tom是下层,此时TomMain依赖于底层Tom,这种情况是不符合软件设计原则的。
## ICourse接口
```text
public interface ICourse {
void study();
}
```
## JavaCourse类
```text
public class JavaCourse implements ICourse{
@Override
public void study() {
System.err.println("Study Java!");
}
}
```
## PythonCourse类
```text
public class PythonCourse implements ICourse{
@Override
public void study() {
System.err.println("Study Python!");
}
}
```
## Tom
```text
public class Tom {
public void study(ICourse course){
course.study();
}
}
```
## TomMain测试类
```java
public class TomMain {
public static void main(String[] args) {
Tom tom = new Tom();
tom.study(new JavaCourse());
tom.study(new PythonCourse());
}
}
```
声明一个课程接口ICourse,然后所有的课程来实现这个接口的study方法,这样增加课程的时候不需要去修改Tom类了,而是创建一个具体的课程累就可以了。
Tom类中不在面向实现编程,而是对
```text
tom.studyCPlusPlus();
tom.studyJava();
tom.studyPython();
```
进行了抽象,结果为一个study方法,提供一个课程类型的参数;
TomMain中传递具体的课程来进行学习,这样主动权就放在了TomMain这一层,所以这样实现了高层对底层依赖的去除。
## 依赖倒置原则的优点
1、 依赖倒置原则可以降低类间的耦合
2、依赖导致原则可以提高系统的稳定性
3、依赖倒置原则可以减少并行开发引起的风险
4、依赖倒置原则可以提高代码的可读性和可维护性
## 依赖导致原则的实现
只要记住一点核心:面向接口编程而不是面向实现编程;
- **每个类尽量提供接口或抽象类,或者两个都具备**
- **变量的声明类型尽量是接口或者抽象类**
- **任何类都不应该从具体类中派生**
- **使用继承时尽量遵循里氏替换原则**