热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

JAVA设原则之依赖倒置原则

JAVA设原则之依赖倒置原则本博客大部分内容来自于网络,写下来方便以后查阅1.什么是依赖倒置原则简单来说A.高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象

JAVA设原则之依赖倒置原则

本博客大部分内容来自于网络,写下来方便以后查阅


1.什么是依赖倒置原则

简单来说
A.高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象。
B.抽象不应该依赖于具体实现,具体实现应该依赖于抽象。

2.为什么要遵循依赖倒置原则
  很多时候我们更改一个需求,发现更改一处地方需要更改多个文件,看见很多的报错我们自己都觉得烦,我们很清醒的意识到这是因为严重的耦合导致的,所以自然要想办法解决这个问题
  
3.依赖倒置有什么好处
  简单来说,解决耦合。一般情况下抽象的变化概率很小,让用户程序依赖于抽象,实现的细节也依赖于抽象。即使实现细节不断变动,只要抽象不变,客户程序就不需要变化。这大大降低了客户程序与实现细节的耦合度。

例子

公司是福特和本田公司的金牌合作伙伴,现要求开发一套自动驾驶系统,只要汽车上安装该系统就可以实现无人驾驶,该系统可以在福特和本田车上使用,只要这两个品牌的汽车使用该系统就能实现自动驾驶。

常规写法

既然是两种不同的汽车,那我们分别定义出来,一个Fute一个Bentian,代码如下:

//福特汽车
public class Fute {

public void run() {
System.out.println("福特汽车启动");

}

public void stop() {
System.out.println("福特汽车停止");

}

}
//本田汽车
public class Bentian{

public void run() {
System.out.println("本田汽车启动");

}

public void stop() {
System.out.println("本田汽车停止");

}

}
//我们的自动驾驶系统
public class AtuoRunSystem {


private String mType;
private Bentian bentian;
private Fute fute;

public AtuoRunSystem(String type){
mType = type ;
bentian = new Bentian();
fute = new Fute();
}
public void AutoRun(){
if ("bentian".equals(mType)) {
bentian.run();
}else {
fute.run();
}
}
public void AutoStop(){
if ("bentian".equals(mType)) {
bentian.stop();
}else {
fute.stop();
}
}
}

代码很简单,相信有java基础的人一看就懂了,但是缺点也很明显,扩展性特别差,现在只有两种车,if-else语句还算简单,假设以后有100种车呢?是不是要改很多文件,写很多的if-else语句,这样岂不是把人忙死,效率很低。
那么,接下来我们开始改造。

首先观察福特和本田两个类

  完全一模一样的代码是不是,那么我们开始抽离,写个抽象类或者接口都可以,这里我们写一个接口,有人纳闷为啥不写抽象类呢?根据我的个人见解,抽象类的抽象方法可以自己实现,但是接口的方法都是由子类实现的,车的功能我们具体细节我们不知道,没必要写出它的实现,所以,我们由子类实现,代码如下

public interface Icar {
void run();
void stop();
}

其次来我们看定义

A.高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象。
B.抽象不应该依赖于具体实现,具体实现应该依赖于抽象。

在上述代码中,我们的AutoRunSystem类严重依赖于具体的子类,比如福特,本田,依赖了低层模块,而定义里已经说明,我们应该依赖于抽象,于是我们改造AutoRunSystem代码
代码如下:

public class AtuoRunSystem {

private Icar icar;

public AtuoRunSystem(Icar icar){
this.icar = icar;
}

public void autoRun(){
icar.run();

}
public void autoStop(){
icar.stop();
}

}

这样我们依赖的就是它的抽象类Icar。

public class Bentian implements Icar{

@Override
public void run() {
System.out.println("本田汽车启动");

}

@Override
public void stop() {
System.out.println("本田汽车停止");

}

}
public class Fute implements Icar{

public void run() {
System.out.println("福特汽车启动");

}

public void stop() {
System.out.println("福特汽车停止");

}

}

这样,我们就抽出了它的共同点。正好也呼应了B点,具体应该依赖于抽象,而不是抽象依赖于具体

这样,在main函数中,我们就可以这么使用了

public class Main {

public static void main(String[] args) {
AtuoRunSystem system = new AtuoRunSystem(new Bentian());
system.autoRun();
AtuoRunSystem system2 = new AtuoRunSystem(new Fute());
system2.autoRun();
}
}

是不是一下子明了多了,而且无论多少量车,我们都不用特别大改,只需要改一下抽象接口,写出它的具体实现,我们其他就不用管了,是不是很棒。
看懂这个,我们以后就可以看MVP模式了~~


推荐阅读
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文介绍了Java高并发程序设计中线程安全的概念与synchronized关键字的使用。通过一个计数器的例子,演示了多线程同时对变量进行累加操作时可能出现的问题。最终值会小于预期的原因是因为两个线程同时对变量进行写入时,其中一个线程的结果会覆盖另一个线程的结果。为了解决这个问题,可以使用synchronized关键字来保证线程安全。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • 本文介绍了一个Java猜拳小游戏的代码,通过使用Scanner类获取用户输入的拳的数字,并随机生成计算机的拳,然后判断胜负。该游戏可以选择剪刀、石头、布三种拳,通过比较两者的拳来决定胜负。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了在Java中gt、gtgt、gtgtgt和lt之间的区别。通过解释符号的含义和使用例子,帮助读者理解这些符号在二进制表示和移位操作中的作用。同时,文章还提到了负数的补码表示和移位操作的限制。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 从零学Java(10)之方法详解,喷打野你真的没我6!
    本文介绍了从零学Java系列中的第10篇文章,详解了Java中的方法。同时讨论了打野过程中喷打野的影响,以及金色打野刀对经济的增加和线上队友经济的影响。指出喷打野会导致线上经济的消减和影响队伍的团结。 ... [详细]
author-avatar
mobiledu2502872825
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有