基本介绍

依赖倒转原则是指:

  1. 高层模块不应该依赖底层模块,二者都应该依赖其抽象
  2. 抽象不应该依赖细节,细节应该依赖抽象
  3. 依赖倒转(倒置)的中心思想是面向接口编程
  4. 依赖倒转原则是基于真阳的设计理念:相对于细节的多变性,抽象的东西要稳定的多。以抽象为基础搭建的架构比以细节为基础的架构要稳定的多。在java中,抽象指的是接口或抽象类,细节就是具体的实现类
  5. 使用接口或抽象类的目的是制定好的规范,而不设计任何的具体操作,把展现的细节任务交给他们实现类去完成

    实例应用

    方案一:

    ```java public class Application {

    public static void main(String[] args) {

    1. Person person = new Person();
    2. 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(); } }

  1. 运行结果:
  2. ```java
  3. "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
  4. 邮件信息:hello world

方案二:

  1. public class Application {
  2. public static void main(String[] args) {
  3. Person person = new Person();
  4. person.run(new Email());
  5. person.run(new WeiXin());
  6. }
  7. }
  8. interface IReceiver{
  9. public void getInfo();
  10. }
  11. class Email implements IReceiver{
  12. public void getInfo(){
  13. System.out.println("邮件信息:hello world");
  14. }
  15. }
  16. class WeiXin implements IReceiver{
  17. public void getInfo(){
  18. System.out.println("微信信息:hello world");
  19. }
  20. }
  21. class Person {
  22. public void run(IReceiver receiver){
  23. receiver.getInfo();
  24. }
  25. }

运行结果:

  1. "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
  2. 邮件信息:hello world
  3. 微信信息:hello world

依赖关系传递的三种方式

构造器传入

  1. public class Application {
  2. public static void main(String[] args) {
  3. Person person = new Person(new WeiXin());
  4. person.run();
  5. }
  6. }
  7. interface IReceiver{
  8. public void getInfo();
  9. }
  10. class Email implements IReceiver{
  11. public void getInfo(){
  12. System.out.println("邮件信息:hello world");
  13. }
  14. }
  15. class WeiXin implements IReceiver{
  16. public void getInfo(){
  17. System.out.println("微信信息:hello world");
  18. }
  19. }
  20. class Person {
  21. private IReceiver receiver;
  22. public Person(IReceiver receiver) {
  23. this.receiver = receiver;
  24. }
  25. public void run(){
  26. receiver.getInfo();
  27. }
  28. }

接口传入

  1. public class Application {
  2. public static void main(String[] args) {
  3. Person person = new Person();
  4. person.run(new Email());
  5. person.run(new WeiXin());
  6. }
  7. }
  8. interface IReceiver{
  9. public void getInfo();
  10. }
  11. class Email implements IReceiver{
  12. public void getInfo(){
  13. System.out.println("邮件信息:hello world");
  14. }
  15. }
  16. class WeiXin implements IReceiver{
  17. public void getInfo(){
  18. System.out.println("微信信息:hello world");
  19. }
  20. }
  21. class Person {
  22. public void run(IReceiver receiver){
  23. receiver.getInfo();
  24. }
  25. }

setter传入

  1. public class Application {
  2. public static void main(String[] args) {
  3. Person person = new Person();
  4. person.setReceiver(new WeiXin());
  5. person.run();
  6. }
  7. }
  8. interface IReceiver{
  9. void getInfo();
  10. }
  11. class WeiXin implements IReceiver{
  12. public void getInfo(){
  13. System.out.println("微信信息:hello world");
  14. }
  15. }
  16. class Person {
  17. private IReceiver receiver;
  18. public void setReceiver(IReceiver receiver) {
  19. this.receiver = receiver;
  20. }
  21. public void run(){
  22. receiver.getInfo();
  23. }
  24. }

依赖倒转原则注意事项和细节

  1. 底层模块尽量都要有抽象类或接口,或者两者都有,程序稳定性更好。
  2. 变量的生命类型尽量都是抽象类或接口,这样我们的变量引用和实际对象间,就存在一个缓冲层,利于程序的扩展和优化
  3. 继承时遵循里氏替换原则