先看一下概念
①高层模块不应该依赖低层模块,二者都应该依赖其抽象
②抽象不应该依赖细节,细节应该依赖抽象
③依赖倒转的核心思想是:面向接口编程
④依赖倒转是基于这样的设计理念:相对于细节的多变性,抽象的东西要稳定的多。以抽象为基础搭建的架构比以细节为基础搭建的架构稳定的多。在java中,抽象指的是接口或者是抽象类,细节就是具体的实现类
⑤使用接口或者抽象类的目的就是制定好规范,而并不涉及任何的具体操作,把展现的细节交给他们的实现类去完成。
依赖关系有三种传递方式
①接口
②构造方法传递
③setter方法传递
注意事项和细节
①低层模块要尽量使用抽象类或者是接口,或者两者都有,这样程序稳定性更好
②变量的申明类型尽量是抽象类或者是接口,这样我们的变量引用和实际的对象间就存在一个缓冲层,利于程序扩展和优化
③继承时候,需要遵循里式替换原则(下一个标题讲解)
再次强调一句话:依赖倒转的核心是【面向接口编程】
先看一段没有遵循依赖倒转原则的代码
1 //miles zhu 2 public class DependecyInversion { 3 4 //测试 5 public static void main(String[] args) { 6 Person person = new Person(); 7 person.receive(new Email()); 8 } 9 10 } 11 12 //首次创建一个Email类,里面有一个方法,直接打印一句话 13 class Email { 14 public String getInfo() { 15 return "电子邮件信息: hello,world"; 16 } 17 } 18 19 20 //然后创建一个Person类,用来发邮件 21 class Person { 22 public void receive(Email email ) { 23 System.out.println(email.getInfo()); 24 } 25 }
解读:这段代码是想实现某个人发送邮件/短信的功能。这段代码非常简单,首先创建了一个Email类,里面有相应的发送信息的方法。然后创建一个Person类去调用这个Emial类中的方法去发送消息。但是如果这个时候,Person发送的不是邮件,而是微信、QQ、短信息?这样还需要在Person中增加相应的recive_wechat方法等等。。。。或者是对receive进行重载,但是这样的设计Person和太对的类进行依赖。很显然这种方式在实际开发中是不可行的。
解决思路:设计一个,然后相应的发信息的类实现该接口即可,Person中的receive只需要依赖接口即可。具体看一下代码
1 public class DependecyInversion { 2 3 public static void main(String[] args) { 4 //客户端无需改变 5 Person person = new Person(); 6 person.receive(new Email()); 7 8 person.receive(new WeiXin()); 9 } 10 11 } 12 13 //定义接口 14 interface IReceiver { 15 public String getInfo(); 16 } 17 18 class Email implements IReceiver { 19 public String getInfo() { 20 return "电子邮件信息: hello,world"; 21 } 22 } 23 24 //增加微信 25 class WeiXin implements IReceiver { 26 public String getInfo() { 27 return "微信信息: hello,ok"; 28 } 29 } 30 31 //方式2 32 class Person { 33 //这里我们是对接口的依赖 34 public void receive(IReceiver receiver ) { 35 System.out.println(receiver.getInfo()); 36 } 37 }
再次强调一句话:依赖倒转的核心是【面向接口编程】
再次强调一句话:依赖倒转的核心是【面向接口编程】
再次强调一句话:依赖倒转的核心是【面向接口编程】