基本介绍
依赖倒转原则是指:
- 高层模块不应该依赖底层模块,二者都应该依赖其抽象
- 抽象不应该依赖细节,细节应该依赖抽象
- 依赖倒转(倒置)的中心思想是面向接口编程
- 依赖倒转原则是基于真阳的设计理念:相对于细节的多变性,抽象的东西要稳定的多。以抽象为基础搭建的架构比以细节为基础的架构要稳定的多。在java中,抽象指的是接口或抽象类,细节就是具体的实现类
使用接口或抽象类的目的是制定好的规范,而不设计任何的具体操作,把展现的细节任务交给他们实现类去完成
实例应用
方案一:
```java public class Application {
public static void main(String[] args) {
Person person = new Person();person.run(new Email());
} }
class Email { public void getInfo(){ System.out.println(“邮件信息:hello world”); } } class Person { //没有可用性 简单比较容易想到 //如果我们想过去的对象是微信,短信等,则需要新增类或者是新增方法 //解决思路:引入一个抽象的接口IReceiver,表示接收者,这样person类与接口IReceiver发生依赖 public void run(Email email){ email.getInfo(); } }
运行结果:```java"F:\Program Files\Java\jdk1.8.0_201\bin\java.exe" "-javaagent:F:\Program Files\JetBrains\IntelliJ IDEA 2018.3\lib\idea_rt.jar=53831:F:\Program Files\JetBrains\IntelliJ IDEA 2018.3\bin" -Dfile.encoding=UTF-8 -classpath "F:\Program Files\Java\jdk1.8.0_201\jre\lib\charsets.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\deploy.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\access-bridge-64.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\cldrdata.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\dnsns.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\jaccess.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\jfxrt.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\localedata.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\nashorn.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\sunec.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\sunjce_provider.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\sunmscapi.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\sunpkcs11.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\zipfs.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\javaws.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\jce.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\jfr.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\jfxswt.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\jsse.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\management-agent.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\plugin.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\resources.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\rt.jar;E:\study\study_jvm\target\classes;F:\JAVA\Maven\Repository\org\springframework\boot\spring-boot-starter-web\2.4.1\spring-boot-starter-web-2.4.1.jar;F:\JAVA\Maven\Repository\org\springframework\boot\spring-boot-starter\2.4.1\spring-boot-starter-2.4.1.jar;F:\JAVA\Maven\Repository\org\springframework\boot\spring-boot\2.4.1\spring-boot-2.4.1.jar;F:\JAVA\Maven\Repository\org\springframework\boot\spring-boot-autoconfigure\2.4.1\spring-boot-autoconfigure-2.4.1.jar;F:\JAVA\Maven\Repository\org\springframework\boot\spring-boot-starter-logging\2.4.1\spring-boot-starter-logging-2.4.1.jar;F:\JAVA\Maven\Repository\ch\qos\logback\logback-classic\1.2.3\logback-classic-1.2.3.jar;F:\JAVA\Maven\Repository\ch\qos\logback\logback-core\1.2.3\logback-core-1.2.3.jar;F:\JAVA\Maven\Repository\org\apache\logging\log4j\log4j-to-slf4j\2.13.3\log4j-to-slf4j-2.13.3.jar;F:\JAVA\Maven\Repository\org\apache\logging\log4j\log4j-api\2.13.3\log4j-api-2.13.3.jar;F:\JAVA\Maven\Repository\org\slf4j\jul-to-slf4j\1.7.30\jul-to-slf4j-1.7.30.jar;F:\JAVA\Maven\Repository\jakarta\annotation\jakarta.annotation-api\1.3.5\jakarta.annotation-api-1.3.5.jar;F:\JAVA\Maven\Repository\org\yaml\snakeyaml\1.27\snakeyaml-1.27.jar;F:\JAVA\Maven\Repository\org\springframework\boot\spring-boot-starter-json\2.4.1\spring-boot-starter-json-2.4.1.jar;F:\JAVA\Maven\Repository\com\fasterxml\jackson\core\jackson-databind\2.11.3\jackson-databind-2.11.3.jar;F:\JAVA\Maven\Repository\com\fasterxml\jackson\core\jackson-annotations\2.11.3\jackson-annotations-2.11.3.jar;F:\JAVA\Maven\Repository\com\fasterxml\jackson\core\jackson-core\2.11.3\jackson-core-2.11.3.jar;F:\JAVA\Maven\Repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.11.3\jackson-datatype-jdk8-2.11.3.jar;F:\JAVA\Maven\Repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.11.3\jackson-datatype-jsr310-2.11.3.jar;F:\JAVA\Maven\Repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.11.3\jackson-module-parameter-names-2.11.3.jar;F:\JAVA\Maven\Repository\org\springframework\boot\spring-boot-starter-tomcat\2.4.1\spring-boot-starter-tomcat-2.4.1.jar;F:\JAVA\Maven\Repository\org\apache\tomcat\embed\tomcat-embed-core\9.0.41\tomcat-embed-core-9.0.41.jar;F:\JAVA\Maven\Repository\org\glassfish\jakarta.el\3.0.3\jakarta.el-3.0.3.jar;F:\JAVA\Maven\Repository\org\apache\tomcat\embed\tomcat-embed-websocket\9.0.41\tomcat-embed-websocket-9.0.41.jar;F:\JAVA\Maven\Repository\org\springframework\spring-web\5.3.2\spring-web-5.3.2.jar;F:\JAVA\Maven\Repository\org\springframework\spring-beans\5.3.2\spring-beans-5.3.2.jar;F:\JAVA\Maven\Repository\org\springframework\spring-webmvc\5.3.2\spring-webmvc-5.3.2.jar;F:\JAVA\Maven\Repository\org\springframework\spring-aop\5.3.2\spring-aop-5.3.2.jar;F:\JAVA\Maven\Repository\org\springframework\spring-context\5.3.2\spring-context-5.3.2.jar;F:\JAVA\Maven\Repository\org\springframework\spring-expression\5.3.2\spring-expression-5.3.2.jar;F:\JAVA\Maven\Repository\org\projectlombok\lombok\1.18.16\lombok-1.18.16.jar;F:\JAVA\Maven\Repository\org\slf4j\slf4j-api\1.7.30\slf4j-api-1.7.30.jar;F:\JAVA\Maven\Repository\org\springframework\spring-core\5.3.2\spring-core-5.3.2.jar;F:\JAVA\Maven\Repository\org\springframework\spring-jcl\5.3.2\spring-jcl-5.3.2.jar" design.Application邮件信息:hello world
方案二:
public class Application {public static void main(String[] args) {Person person = new Person();person.run(new Email());person.run(new WeiXin());}}interface IReceiver{public void getInfo();}class Email implements IReceiver{public void getInfo(){System.out.println("邮件信息:hello world");}}class WeiXin implements IReceiver{public void getInfo(){System.out.println("微信信息:hello world");}}class Person {public void run(IReceiver receiver){receiver.getInfo();}}
运行结果:
"F:\Program Files\Java\jdk1.8.0_201\bin\java.exe" "-javaagent:F:\Program Files\JetBrains\IntelliJ IDEA 2018.3\lib\idea_rt.jar=53988:F:\Program Files\JetBrains\IntelliJ IDEA 2018.3\bin" -Dfile.encoding=UTF-8 -classpath "F:\Program Files\Java\jdk1.8.0_201\jre\lib\charsets.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\deploy.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\access-bridge-64.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\cldrdata.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\dnsns.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\jaccess.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\jfxrt.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\localedata.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\nashorn.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\sunec.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\sunjce_provider.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\sunmscapi.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\sunpkcs11.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\zipfs.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\javaws.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\jce.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\jfr.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\jfxswt.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\jsse.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\management-agent.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\plugin.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\resources.jar;F:\Program Files\Java\jdk1.8.0_201\jre\lib\rt.jar;E:\study\study_jvm\target\classes;F:\JAVA\Maven\Repository\org\springframework\boot\spring-boot-starter-web\2.4.1\spring-boot-starter-web-2.4.1.jar;F:\JAVA\Maven\Repository\org\springframework\boot\spring-boot-starter\2.4.1\spring-boot-starter-2.4.1.jar;F:\JAVA\Maven\Repository\org\springframework\boot\spring-boot\2.4.1\spring-boot-2.4.1.jar;F:\JAVA\Maven\Repository\org\springframework\boot\spring-boot-autoconfigure\2.4.1\spring-boot-autoconfigure-2.4.1.jar;F:\JAVA\Maven\Repository\org\springframework\boot\spring-boot-starter-logging\2.4.1\spring-boot-starter-logging-2.4.1.jar;F:\JAVA\Maven\Repository\ch\qos\logback\logback-classic\1.2.3\logback-classic-1.2.3.jar;F:\JAVA\Maven\Repository\ch\qos\logback\logback-core\1.2.3\logback-core-1.2.3.jar;F:\JAVA\Maven\Repository\org\apache\logging\log4j\log4j-to-slf4j\2.13.3\log4j-to-slf4j-2.13.3.jar;F:\JAVA\Maven\Repository\org\apache\logging\log4j\log4j-api\2.13.3\log4j-api-2.13.3.jar;F:\JAVA\Maven\Repository\org\slf4j\jul-to-slf4j\1.7.30\jul-to-slf4j-1.7.30.jar;F:\JAVA\Maven\Repository\jakarta\annotation\jakarta.annotation-api\1.3.5\jakarta.annotation-api-1.3.5.jar;F:\JAVA\Maven\Repository\org\yaml\snakeyaml\1.27\snakeyaml-1.27.jar;F:\JAVA\Maven\Repository\org\springframework\boot\spring-boot-starter-json\2.4.1\spring-boot-starter-json-2.4.1.jar;F:\JAVA\Maven\Repository\com\fasterxml\jackson\core\jackson-databind\2.11.3\jackson-databind-2.11.3.jar;F:\JAVA\Maven\Repository\com\fasterxml\jackson\core\jackson-annotations\2.11.3\jackson-annotations-2.11.3.jar;F:\JAVA\Maven\Repository\com\fasterxml\jackson\core\jackson-core\2.11.3\jackson-core-2.11.3.jar;F:\JAVA\Maven\Repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.11.3\jackson-datatype-jdk8-2.11.3.jar;F:\JAVA\Maven\Repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.11.3\jackson-datatype-jsr310-2.11.3.jar;F:\JAVA\Maven\Repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.11.3\jackson-module-parameter-names-2.11.3.jar;F:\JAVA\Maven\Repository\org\springframework\boot\spring-boot-starter-tomcat\2.4.1\spring-boot-starter-tomcat-2.4.1.jar;F:\JAVA\Maven\Repository\org\apache\tomcat\embed\tomcat-embed-core\9.0.41\tomcat-embed-core-9.0.41.jar;F:\JAVA\Maven\Repository\org\glassfish\jakarta.el\3.0.3\jakarta.el-3.0.3.jar;F:\JAVA\Maven\Repository\org\apache\tomcat\embed\tomcat-embed-websocket\9.0.41\tomcat-embed-websocket-9.0.41.jar;F:\JAVA\Maven\Repository\org\springframework\spring-web\5.3.2\spring-web-5.3.2.jar;F:\JAVA\Maven\Repository\org\springframework\spring-beans\5.3.2\spring-beans-5.3.2.jar;F:\JAVA\Maven\Repository\org\springframework\spring-webmvc\5.3.2\spring-webmvc-5.3.2.jar;F:\JAVA\Maven\Repository\org\springframework\spring-aop\5.3.2\spring-aop-5.3.2.jar;F:\JAVA\Maven\Repository\org\springframework\spring-context\5.3.2\spring-context-5.3.2.jar;F:\JAVA\Maven\Repository\org\springframework\spring-expression\5.3.2\spring-expression-5.3.2.jar;F:\JAVA\Maven\Repository\org\projectlombok\lombok\1.18.16\lombok-1.18.16.jar;F:\JAVA\Maven\Repository\org\slf4j\slf4j-api\1.7.30\slf4j-api-1.7.30.jar;F:\JAVA\Maven\Repository\org\springframework\spring-core\5.3.2\spring-core-5.3.2.jar;F:\JAVA\Maven\Repository\org\springframework\spring-jcl\5.3.2\spring-jcl-5.3.2.jar" design.Application邮件信息:hello world微信信息:hello world
依赖关系传递的三种方式
构造器传入
public class Application {public static void main(String[] args) {Person person = new Person(new WeiXin());person.run();}}interface IReceiver{public void getInfo();}class Email implements IReceiver{public void getInfo(){System.out.println("邮件信息:hello world");}}class WeiXin implements IReceiver{public void getInfo(){System.out.println("微信信息:hello world");}}class Person {private IReceiver receiver;public Person(IReceiver receiver) {this.receiver = receiver;}public void run(){receiver.getInfo();}}
接口传入
public class Application {public static void main(String[] args) {Person person = new Person();person.run(new Email());person.run(new WeiXin());}}interface IReceiver{public void getInfo();}class Email implements IReceiver{public void getInfo(){System.out.println("邮件信息:hello world");}}class WeiXin implements IReceiver{public void getInfo(){System.out.println("微信信息:hello world");}}class Person {public void run(IReceiver receiver){receiver.getInfo();}}
setter传入
public class Application {public static void main(String[] args) {Person person = new Person();person.setReceiver(new WeiXin());person.run();}}interface IReceiver{void getInfo();}class WeiXin implements IReceiver{public void getInfo(){System.out.println("微信信息:hello world");}}class Person {private IReceiver receiver;public void setReceiver(IReceiver receiver) {this.receiver = receiver;}public void run(){receiver.getInfo();}}
依赖倒转原则注意事项和细节
- 底层模块尽量都要有抽象类或接口,或者两者都有,程序稳定性更好。
- 变量的生命类型尽量都是抽象类或接口,这样我们的变量引用和实际对象间,就存在一个缓冲层,利于程序的扩展和优化
- 继承时遵循里氏替换原则
