依赖倒置原则
1.高层模块不要依赖底层模块,二者都应该依赖其抽象 2.抽象不依赖细节,细节应该依赖抽象(抽象指的是接口,或者抽象类,细节指的是具体实现类) 3.中心思想是面向接口编程
在开发中,比如我们定义一个接收信息的方法,方法参数上传入相应信息的对象,那么我接收邮件信息就传入邮件信息对象,接收其他信息,就要重新定义一个方法,方法参数放其他信息对应的类。当我们为其扩展功能时,就要在类中不断增加相应方法,这样显然是冗余和低效的。
例:
class Person{
// 这种方案简单,但Person中方法依赖Mail类,耦合性大,如果要接收其他信息,就要添加其他类和其他接收方法
public void receiveMail(Mail mail){
mail.info();
}
public void receiveMail(Weixin weixin){
weixin.info();
}
}
class Mail{
public void info(){
System.out.println("邮件信息");
}
}
class Weixin{
public void info(){
System.out.println("weixin信息");
}
}
那么该如何改进呢?
首先,这几个类都有一个类似的方法,接收信息,那么,我们将其封装成一个接口,如果要新增接收比如微信信息的功能,就创建一个类,继承该接口,并重写该方法为自己的业务逻辑即可(扩展自己的细节类)这样,我们就把依赖从类,变成接口了,之后想要接收新的类型的信息,只要传入相应细节类对象即可
上代码:
//方案:定义一个接口表示接收者,让Person类与接口发生依赖,因为接收信息都是属于接收范畴,接收各种信息,只要各自实现接口即可
interface IReceive{
void getInfo();
}
//获取邮件信息
class Mail2 implements IReceive{
@Override
public void getInfo() {
System.out.println("获取mail信息");
}
}
//获取微信信息
class Mail3 implements IReceive{
@Override
public void getInfo() {
System.out.println("获取微信信息");
}
}
class Person2{
public void receiveMail(IReceive receive){
receive.getInfo();
}
}
依赖传递的三种方式: 1.接口传递 2.构造方法 3.getter方法
接口传递:
// 方式1: 通过接口传递实现依赖
interface ITV { //ITV接口
public void play();
}
//细节类
class ITVService implements ITV{
@Override
public void play() {
System.out.println("通过接口传递依赖");
}
}
// 开关的接口
interface IOpenAndClose {
public void open(ITV tv); //抽象方法,接收接口
}
// 实现接口
class OpenAndClose implements IOpenAndClose{
public void open(ITV tv){
tv.play();
}
}
构造方法
方式2: 通过构造方法依赖传递
interface IOpenAndClose {
public void open(); //抽象方法
}
interface ITV { //ITV接口
public void play();
}
//细节类
class ITVService implements ITV{
@Override
public void play() {
System.out.println("通过构造方法传递依赖");
}
}
class OpenAndClose implements IOpenAndClose{//new这个类时将细节类传过来即可
public ITV tv;
public OpenAndClose(ITV tv){
this.tv = tv;
}
@Override
public void open(){
this.tv.play();
}
}
通过setter方法
方式3 , 通过setter方法传递
interface IOpenAndClose {
public void open(); // 抽象方法
public void setTv(ITV tv);
}
interface ITV { // ITV接口
public void play();
}
//细节类
class ITVService implements ITV{
@Override
public void play() {
System.out.println("通过set传递依赖");
}
}
class OpenAndClose implements IOpenAndClose {
private ITV tv;
public void setTv(ITV tv) {
this.tv = tv;
}
public void open() {
this.tv.play();
}
}