基本介绍

依赖原则是指:

高层模块不应该依赖底层模块,二者都应该依赖其抽象

抽象不应该依赖细节,细节应该依赖抽象

依赖倒转的中心思想是面向接口编程

依赖倒转原则是基于这样的设计理念:相对于细节的多变性,抽象的东西要稳定的多。以抽象为基础搭建的架构比细节为基础的架构要稳定的多。在java中,抽象指的是接口或抽象类,细节就是具体的实现类。

使用接口或抽象类的目的是制定好规范,而不涉及任何具体的操作,把展现细节的任务交给他们的实现类去完成

 

应用实例

Person接受消息的功能

 

方式一:

package cn.rabcheng.dependenceinversion;

/**
* @auther cheng
* @create 2020-08-13 22:41
* 依赖倒转原则
*/
public class dependenceinversion1 {
public static void main(String[] args) {

Person person = new Person();
person.receive(new Email());
person.receive2(new Weixin());


}
}

class Email{
public String getInfo(){
return "电子邮件信息:hello world";
}
}

class Weixin{
public String getInfo(){
return "微信消息:hello ok";
}
}

//完成Person接受消息的功能
class Person{
public void receive(Email email){
System.out.println(email.getInfo());
}

public void receive2(Weixin weixin){
System.out.println(weixin.getInfo());

}
}

电子邮件信息:hello world
微信消息:hello ok

方式一的分析:

简单,比较容易想到、实现

如果我们获取的对象是微信、短信等等,则新增类,同时Person也要增加相应的接受方法

解决思路:引入一个抽象的接口IReceiver,表示接收者,这样Person类与IReceiver发生依赖

因为Email,Weixin等等属于接收的范围,他们各自实现IReceiver接口就行,这样我们就符合依赖倒转的原则

 

方式二:

 1 package cn.rabcheng.dependenceinversion;
 2 
 3 /**
 4  * @auther cheng
 5  * @create 2020-08-13 22:57
 6  * 依赖倒转原则
 7  */
 8 public class dependenceinversion2 {
 9     public static void main(String[] args) {
10 
11         //客户端无需改变
12         Person2 person2 = new Person2();
13         person2.receive(new Email2());
14         person2.receive(new Weixin2());
15 
16 
17     }
18 }
19 
20 //定义接口
21 interface IReceiver{
22     String getInfo();
23 }
24 
25 
26 class Email2 implements IReceiver{
27     @Override
28     public String getInfo() {
29         return "电子邮件信息:hello world";
30     }
31 }
32 
33 //增加微信
34 class Weixin2 implements IReceiver{
35     @Override
36     public String getInfo() {
37         return "微信消息:hello ok";
38     }
39 }
40 
41 class Person2{
42     //person2依赖接口
43     public void receive(IReceiver iReceiver){
44         System.out.println(iReceiver.getInfo());
45     }
46 }
47 电子邮件信息:hello world
48 微信消息:hello ok

这样只需要增加Weixin类,不用增加Person类里面的方法,让Person类和IReceiver发生依赖关系。

 

依赖关系传递的三种方式和应用案例

接口传递

构造方法传递

setter方法传递

  1 package cn.rabcheng.dependenceinversion;
  2 
  3 /**
  4  * @auther cheng
  5  * @create 2020-08-13 23:10
  6  * 依赖传递
  7  */
  8 public class DependencyPass {
  9     public static void main(String[] args) {
 10 
 11 //        方式一:通过接口传递
 12 //        Open open = new Open();
 13 //        open.open(new XiaoMi());
 14 
 15 //        方式二:通过构造方法传递
 16 //        Open open = new Open(new XiaoMi());
 17 //        open.open();
 18 
 19 //        方式三:通过setter方法传递
 20         Open open = new Open();
 21         XiaoMi xiaoMi = new XiaoMi();
 22         open.setter(xiaoMi);
 23         open.open();
 24     }
 25 }
 26 
 27 //方式一:通过接口传递依赖
 28 //开电视的接口
 29 //interface IOpen{
 30 //    void open(ITV itv);
 31 //}
 32 //
 33 ////电视机接口
 34 //interface ITV{
 35 //    void play();
 36 //}
 37 //
 38 //class XiaoMi implements ITV{
 39 //    @Override
 40 //    public void play() {
 41 //        System.out.println("小米电视,打开");
 42 //    }
 43 //}
 44 //
 45 //class Open implements IOpen{
 46 //    @Override
 47 //    public void open(ITV itv) {
 48 //        itv.play();
 49 //    }
 50 //}
 51 
 52 //方式二:通过构造方法传递依赖
 53 //interface IOpen{
 54 //    void open();
 55 //}
 56 //
 57 //interface ITV{
 58 //    void play();
 59 //}
 60 //
 61 //class XiaoMi implements ITV{
 62 //    @Override
 63 //    public void play() {
 64 //        System.out.println("小米电视,打开");
 65 //    }
 66 //}
 67 //
 68 //class Open implements IOpen{
 69 //    private ITV itv;
 70 //    public Open(ITV itv) {
 71 //        this.itv = itv;
 72 //    }
 73 //
 74 //    @Override
 75 //    public void open() {
 76 //        this.itv.play();
 77 //    }
 78 //}
 79 
 80 
 81 //方式三:通过setter方法传递
 82 interface IOpen{
 83     void open();
 84 }
 85 
 86 interface ITV{
 87     void play();
 88 }
 89 
 90 class Open implements IOpen{
 91     private ITV itv;
 92 
 93     public void setter(ITV itv){
 94         this.itv = itv;
 95     }
 96     @Override
 97     public void open() {
 98         this.itv.play();
 99     }
100 }
101 
102 class XiaoMi implements ITV{
103     @Override
104     public void play() {
105         System.out.println("小米电视,打开");
106     }
107 }

 

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

底层模块尽量都要有抽象类或接口,或者两者都有,程序稳定性更好

变量的声明类型尽量是抽象类或接口,这样我们的变量引用和实际对象间,就存在一个缓冲层,利于程序扩展和优化

继承时应遵循里氏替换原则

 

posted on 2020-08-13 23:38  -星星点灯丶  阅读(80)  评论(0编辑  收藏  举报