依赖倒置原则
定义:
高层模块不应该依赖于底层模块,二者都应该依赖其抽象。
抽象不应该依赖细节;细节应该依赖抽象。
针对接口编程,不要针对实现编程。
优点:
可以减少类间的耦合性、提高系统稳定性,提高代码可读性和可维护性,可以降低修改程序所造成的风险。
问题由来:
类A直接依赖类B,假如要将类B改为依赖类C,则必须通过修改类A的代码来达成。这种场景下,类A一般是高层模块,负责复杂的业务逻辑,类B和类C是底层模块,负责基本的原子操作;假如要修改A,会给程序带来不必要的风险。
解决方案:
将类A修改为依赖接口I,类B和类C各自实现接口I,类A通过接口I间接与类B和类C发生联系。
代码示例:
假设有这么一个场景,有一个名为Geely的人,有学习java、fe的方法:
- Geely.java
package com.design.principle.dependenceinversion;
/**
* @Author: JLU Tiger
* @Date: 2019/8/29 15:48
*/
public class Geely {
public void studyJavaCourse() {
System.out.println("Geely 在学习Java课程");
}
public void studyFeCourse() {
System.out.println("Geely 在学习FE课程");
}
}
- Test.java
package com.design.principle.dependenceinversion;
/**
* @Author: JLU Tiger
* @Date: 2019/8/29 15:52
*/
public class Test {
public static void main(String[] args) {
Geely geely = new Geely();
geely.studyJavaCourse();
geely.studyFeCourse();
}
}
那如果现在Geely想要学习Python课程,那就需要将Geely.java修改为:
- Geely.java
package com.design.principle.dependenceinversion;
/**
* @Author: JLU Tiger
* @Date: 2019/8/29 15:48
*/
public class Geely {
public void studyJavaCourse() {
System.out.println("Geely 在学习Java课程");
}
public void studyFeCourse() {
System.out.println("Geely 在学习FE课程");
}
public void studyPythonCourse() {
System.out.println("Geely 在学习Python课程");
}
}
这种做法,就是面向实现编程,因为整个Geely就是一个实现类。这个实现类是要经常修改的,扩展性非常差。Test类是属于应用层的,高层的模块不应该依赖低层次的Geely,那我们试着解决这个问题。
首先创建接口:
- ICourse.java
package com.design.principle.dependenceinversion;
/**
* @Author: JLU Tiger
* @Date: 2019/8/29 16:06
*/
public interface ICourse {
void studyCourse();
}
具体实现什么课程,我们交给高层去实现。
- JavaCourse.java
package com.design.principle.dependenceinversion;
/**
* @Author: JLU Tiger
* @Date: 2019/8/29 16:07
*/
public class JavaCourse implements ICourse {
public void studyCourse() {
System.out.println("Geely 在学习Java课程");
}
}
- FeCourse.java
package com.design.principle.dependenceinversion;
/**
* @Author: JLU Tiger
* @Date: 2019/8/29 16:08
*/
public class FeCourse implements ICourse {
public void studyCourse() {
System.out.println("Geely 在学习FE课程");
}
}
对Geely类进行修改:
- Geely.java
package com.design.principle.dependenceinversion;
/**
* @Author: JLU Tiger
* @Date: 2019/8/29 15:48
*/
public class Geely {
public void studyImoocCourse(ICourse iCourse) {
iCourse.studyCourse();
}
}
测试类:
- Test.java
package com.design.principle.dependenceinversion;
/**
* @Author: JLU Tiger
* @Date: 2019/8/29 15:52
*/
public class Test {
public static void main(String[] args) {
Geely geely = new Geely();
geely.studyImoocCourse(new JavaCourse());
geely.studyImoocCourse(new FeCourse());
}
}
这样就尽量的减少了耦合,如果需要扩展,直接创建类实现ICourse即可。