一、依赖倒置原则介绍
依赖倒置原则的定义如下:
High level modules should not depend upon low level modules,Both should depend upon abstractions.Abstractions should not depend upon details.Details should depend upon abstracts.
翻译过来的意思是:高层模块不应该依赖底层模块,两者应该依赖其抽象。抽象不应该依赖细节,细节应该依赖抽象。简单的说就是,程序依赖于抽象接口,不依赖于具体实现。依赖倒置的中心思想是面向接口编程。
依赖倒置原则是基于这样的设计理念:相对于细节的多变性,抽象的东西要稳定得多,以抽象为基础搭建的架构要比细节为基础的架构稳定得多。在Java中,抽象指的是接口或抽象类,而细节指的是具体的实现类。使用接口或抽象类的目的是制定好规范,而不涉及任何具体的操作,把展现细节的任务交给它们的实现类去完成。
二、案例讲解
2.1应用案例
创建一个Person类来接收信息。方式1实现代码如下:
public class Person{
public void receive(Email email){
System.out.println(email.getInfo);
}
}
public class Email{
public String getInfo(){
return "hello Jachen";
}
}
public void Test{
public static void main(String[] args){
Person person = new Person();
person.receive(new Email());
}
}
对于方式1的实现方案,代码简单,比较容易想到。但是如果我们的获取对象是微信、短信等,则需要新增类,同时Person类也要增加相应的接收方法,这样改动会很大。为了解决这个问题,引入一个抽象的接口IReceiver,表示接受者,这样Person类与接口发现依赖。因为电子邮件、微信等等属于接收的范围,他们各自实现IReceiver接口即可,这样就符合依赖倒置原则。
2.2使用依赖倒置原则改造
依赖关系传递有三种方式:1)接口传递;2)构造方法传递;3)setter方法传递。接下来我们逐一讲解这三种依赖关系传递方式。
2.2.1接口传递
1)创建IReceive接口
public Interface IReceive{
String getInfo();
}
2)将Person类的receive方法入参改为IReceive接口
public class Person{
public void receive(IReceive receive){
System.out.println(receive.getInfo);
}
}
3)Email类实现IReceive接口
public class Email implements IReceive{
public String getInfo(){
return "hello Jachen";
}
}
2.2.2构造方法传递
1)创建IReceive接口
public Interface IReceive{
String getInfo();
}
2)在Person类增加IReceive属性,并在构造器中进行赋值
public class Person{
private IReceive receive;
public Person(IReceive receive){
this.receive = receive;
}
public void receive(){
System.out.println(receive.getInfo);
}
}
3)Email类实现IReceive接口
public class Email implements IReceive{
public String getInfo(){
return "hello Jachen";
}
}
2.2.3setter方法传递
1)创建IReceive接口
public Interface IReceive{
String getInfo();
}
2)在Person类增加IReceive属性,并在setter方法中进行赋值
public class Person{
private IReceive receive;
public void setReceive(IReceive receive){
this.receive = receive;
}
public void receive(){
System.out.println(receive.getInfo);
}
}
3)Email类实现IReceive接口
public class Email implements IReceive{
public String getInfo(){
return "hello Jachen";
}
}
三、依赖倒置原则注意事项和细节
1)低层模块尽量都要有抽象类或接口,或者两者都有,程序稳定性更好
2)变量的声明类型尽量是抽象类或接口,这样我们的变量引用和实际对象间就存在一个缓冲层,利于程序扩展和优化
3)继承时遵循里氏替换原则