1.基本介绍
- 1)高层模块不应该依赖底层模块,二者都应该依赖其抽象
- 2)抽象不应该依赖细节,细节应该依赖抽象
- 3)依赖倒置的中心思想是面向接口编程
- 4)相对于细节的多变性,抽象的东西要稳定的多。以抽象为基础搭建的架构比以细节为基础的架构要稳定的多。在java中,抽象指的是接口或抽象类,细节就是具体的实现类
- 5)使用接口或抽象类的目的是制定好规范,而不涉及任何具体的操作,把展现细节的任务交给他们的实现类去完成
2.应用案例
- 案例描述
定义一个Person类,用于接收Email等其它消息 - 最容易想到的实现方式
public class DependenceInversion { public static void main(String[] args) { Person person =new Person(); person.receive(new Email()); } } class Email{ public String getInfo(){ return "电子邮件信息来了"; } } class Person{ public void receive(Email email){ System.out.println(email.getInfo()); } }
上面的这种方式比较最先容易想到,实现起来比较简单,但是存在问题:如果接受的对象为其他信息(比如:微信,信件),则需要新增类,并且Person也要增加相应的接收方法
解决思路:
引入一个抽象的即可IReceiver,表示接收者,这样Persion类与接口IReceiver发生依赖,只需要Email,weixin各自实现IReceiver接口即可,新增其他接收其它对象,无需修改Person类,这样就符合依赖倒置原则
- 采用依赖倒置原则实现
public class DependenceInversion { public static void main(String[] args) { Person person =new Person(); person.receive(new Email()); person.receive(new Weixin()); } } interface IReceiver{ String getInfo(); } class Email implements IReceiver{ public String getInfo(){ return "电子邮件信息来了"; } } class Weixin implements IReceiver{ public String getInfo(){ return "微信消息来了"; } } class Person{ public void receive(IReceiver receiver){ System.out.println(receiver.getInfo()); } }
采用依赖倒置原则实现,这样新增了其它接收对象,只需要被接收的实现IReceiver接口即可,Persion类无需修改任何的代码
3.注意事项和细节
- 依赖关系传递的方法
接口传递
构造方法传递
setter方式传递 - 底层模块尽量都要由抽象类或接口,或者两者都有,程序稳定性更好
- 变量的声明类型尽量是抽象类或接口,这样变量引用和实际对象间,就存在一个缓冲层,利于程序扩展和优化
- 继承时遵循里氏替换原则