携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第5天,点击查看活动详情
简介
依赖倒置的官方定义是:
1、上层模块不应该依赖底层模块,它们都应该依赖于抽象。
2、抽象不应该依赖于细节,细节应该依赖于抽象。
咋一看,这貌似说的就是面向接口编程。我们细细学来看看。
案例
就拿我们经常使用的AI能力调用来举例。我们在开发中经常需要使用各个AI厂家的OCR识别能力来读取身份证,那我们有AI能力的厂家就多了,阿里腾讯合合商汤等等。一开始我们用大厂的阿里腾讯。
public class AlibabaOcr {
/**
* 读取正面
* @return
*/
public String readFront() {
return "广州市公安局";
}
/**
* 读取反面
* @return
*/
public String readBack() {
return "12324567";
}
}
public class TententOcr {
/**
* 读取正面
* @return
*/
public String readFront() {
return "杭州市公安局";
}
/**
* 读取反面
* @return
*/
public String readBack() {
return "22324567";
}
}
public class IdRecognize {
public String orc() {
AlibabaOcr alibabaOcr = new AlibabaOcr();
return alibabaOcr.readFront();
}
public static void main(String[] args) {
IdRecognize idRecognize = new IdRecognize();
idRecognize.orc();
}
}
没毛病,身份证顺利识别出来了。
可是有一点老板发现OCR的成本太高了,不行,挣几个钱全部交给阿里做OCR了,于是吵着叫商户去找性价比更高的厂商。商务不辱使命终于找到合合的价格比上面两个大厂便宜了不少,于是老板兴高采烈地立马给开发说:换!马上给我换!
可是我们发现要换厂商我们就要修改IdRecognize的ocr方法,这是一个业务方法,改起来还是很容易有风险的。立马暴露出来之前的设计是有缺陷的。上层IdRecognize类严重地依赖来了下层的AlibabaOcr、TententOcr这些底层的能力类。
按照咱们依赖倒置原则,咱们应该这样写:
首先,增加一个OCR能力的接口
public interface OcrAbility {
/**
* 读取正面
* @return
*/
String readFront();
/**
* 读取反面
* @return
*/
String readBack();
}
然后各个厂商的OCR能力都去实现它,比如新增的合合厂家:
public class HeheOcr implements OcrAbility{
@Override
public String readFront() {
return "徐州市公安局";
}
@Override
public String readBack() {
return "234567";
}
}
那我们的业务实现依赖下层的抽象,即依赖接口OrcAbility的抽象方法:
public class IdRecognize {
private OcrAbility ocrAbility;
public IdRecognize(OcrAbility ability) {
ocrAbility = ability;
}
public String ocr() {
return ocrAbility.readFront();
}
/**真实调用**/
public static void main(String[] args) {
IdRecognize idRecognize = new IdRecognize(new HeheOcr());
System.out.println(idRecognize.ocr());;
}
}
这样依赖,在真实调用方法里我们想用什么厂家就用什么厂家的能力,而不用去改orc()方法里的内容了。这里同样满足对拓展开放,对修改关闭的开闭原则。
而这里的orcAbility的指定我们是通过构造方法设置进去的,当然这里还可以通过set方法设置进去,这里就和我们Spring的依赖注入很相似了,其实Spring里的接口注入这里也是这种思想。
总结
总的来说,依赖倒置原则的本质就是通过抽象(抽象类或接口)使各个类或模块实现彼此独立,用抽象去定义需要被调用的能力,不互相影响,实现模块间的松耦合。
但是依赖倒置原则定义中的抽象不应该依赖于细节,细节应该依赖于抽象我没有get到它的含义,望哪位大佬指点迷津。