例子
假设小明想要学习网络课程,包括Java,JavaScript,Python等
代码
1、 版本v1
首先创建一个人的实体类,里面包括各种课程的学习方法
public class Person {
public Person() {
}
public void studyJavaCourse() {
System.out.println("学习了Java");
}
public void studyJavaScriptCourse() {
System.out.println("学习了JavaScript");
}
public void studyPythonCourse() {
System.out.println("学习了Python");
}
}
测试
public class Test {
//版本v1
public static void main(String[] args) {
Person person = new Person();
person.studyJavaCourse();
person.studyJavaScriptCourse();
person.studyPythonCourse();
}
}
版本v1的这种方式显然不好,每当小明要学习新课程时,首先需要修改Person
这个实体类,然后修改测试类。这里Test类即高层模块,Person类即底层模块,v1的高层模块每次修改时都需要依赖底层模块,即是不符合依赖倒置原则的
2、版本v2
public interface ICourse {
void studyCourse();
}
public class JavaCourse implements ICourse {
public void studyCourse() {
System.out.println("学习了Java");
}
}
public class JavaScriptCourse implements ICourse {
public void studyCourse() {
System.out.println("学习了JavaScript");
}
}
public class PythonCourse implements ICourse {
public void studyCourse() {
System.out.println("学习了Python");
}
}
测试
public class Test {
//版本v2
public static void main(String[] args) {
Person person = new Person();
person.studyNetCourse(new JavaCourse());
person.studyNetCourse(new JavaScriptCourse());
person.studyNetCourse(new PythonCourse());
}
}
版本v2把学习网络课程进行了抽象,通过创建三个实现类,把抽象类作为Person
类的参数,这样每当Person
需要学习新课程时只需要添加一个ICourse
的实现类即可,这样高层模块Test只需要传入ICourse
的实现类即可学习新课程,不需要修改底层模块。
扫描二维码关注公众号,回复:
8904314 查看本文章
3、版本v3
public class Person {
private ICourse iCourse;
public Person(ICourse iCourse) {//构造器注入
this.iCourse = iCourse;
}
public void studyNetCourse() {
iCourse.studyCourse();
}
}
public class Test {
//版本v3
public static void main(String[] args) {
Person person = new Person(new JavaCourse());
person.studyNetCourse();
}
}
版本v3是通过构造器注入,则在调用studyNetCourse
时不需要关心传入的参数,在构造函数中传入即可,但是也有一个弊端就是每次学习新课程需要重新new一个Person对象
4、版本v4
public class Person {
private ICourse iCourse;
public Person() {
}
public void setCourse(ICourse iCourse) {
this.iCourse = iCourse;
}
public void studyNetCourse() {
iCourse.studyCourse();
}
}
public class Test {
//版本v4
public static void main(String[] args) {
Person person = new Person();
person.setCourse(new JavaCourse());
person.studyNetCourse();
person.setCourse(new JavaScriptCourse());
person.studyNetCourse();
person.setCourse(new PythonCourse());
person.studyNetCourse();
}
}
版本v4通过set方法设置学习的课程,studyNetCourse
不需要关心传入的课程,具体的调用通过setCourse
设置即可