依赖倒转原则(DIP): 高层模块不应该依赖低层模块,两者都应该依赖其抽象抽象不应该依赖细节,细节应该依赖抽象。

依赖倒置原则在Java语言中的表现:

模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生的
接口或抽象类不依赖于实现类
实现类依赖于接口或抽象类

更为精简的定义: 面向接口编程(Object-Oriented Design, OOD)

DIP的好处: 采用依赖倒置原则可以减少类间的耦合性,提高系统的稳定性,降低并行开发引起的风险,提高代码的可读性和可维护性。

DIP的几种写法

接口声明依赖对象: 在接口的方法中声明依赖对象。
构造函数传递依赖对象: 在类中通过构造函数声明依赖对象(好比Spring中的构造器注入),采用构造器注入。
Setter方法传递依赖对象: 在抽象中设置Setter方法声明依赖对象(Spring中的方法注入)。

依赖倒置原则的本质: 就是通过抽象(抽象类或接口)使各个类或模块实现彼此独立,不互相影响,实现模块间的松耦合。

在项目中使用这个规则需要以下原则;

每个类尽量都要有接口或抽象类,或者抽象类和接口都有: 依赖倒置原则的基本要求,有抽象才能依赖倒置。
变量的表面类型尽量是接口或者抽象类。
任何类都不应该从具体类派生。
尽量不要重写基类已经写好的方法(里式替换原则)。
结合里式替换原则来使用: 结合里式替换原则和依赖倒置原则我们可以得出一个通俗的规则,接口负责定义public属性和方法,并且声明与其他对象的依赖关系,抽象类负责公共构造部分的实现,实现类准确的实现业务逻辑,同时在适当的时候对父类进行细化。

一句话:依赖倒置原则的核心就是面向抽象(抽象类或者接口)编程

案例1:
未遵守依赖倒转原则

组装电脑:
现要组装一台电脑,需要配件cpu,硬盘,内存条。只有这些配置都有了,计算机才能正常的运行。选择cpu有很多选择,如Intel,AMD等,硬盘可以选择希捷,西数等,内存条可以选择金士顿,海盗船等。

类图

希捷硬盘类

/*** 希捷硬盘*/
public class XiJieHardDisk {//存储数据的方法public void save(String data) {System.out.println("使用希捷硬盘存储数据为:" + data);}//获取数据的方法public String get() {System.out.println("使用希捷硬盘取数据");return "数据";}
}

金士顿内存条类

/*** 金士顿内存条类*/
public class KingstonMemory {public void save() {System.out.println("使用金士顿内存条");}
}

因特尔cup类

/*** Intel cpu*/
public class IntelCpu {public void run() {System.out.println("使用Intel处理器");}
}

电脑类

/*** Computer*/
public class Computer {private XiJieHardDisk hardDisk;private IntelCpu cpu;private KingstonMemory memory;public XiJieHardDisk getHardDisk() {return hardDisk;}public void setHardDisk(XiJieHardDisk hardDisk) {this.hardDisk = hardDisk;}public IntelCpu getCpu() {return cpu;}public void setCpu(IntelCpu cpu) {this.cpu = cpu;}public KingstonMemory getMemory() {return memory;}public void setMemory(KingstonMemory memory) {this.memory = memory;}public void run() {System.out.println("运行计算机");String data = hardDisk.get();System.out.println("从硬盘上获取的数据是:" + data);cpu.run();memory.save();}
}

测试类(测试组装的电脑)

/*** ComputerDemo*/
public class ComputerDemo {public static void main(String[] args) {//创建组件对象XiJieHardDisk hardDisk = new XiJieHardDisk();IntelCpu cpu = new IntelCpu();KingstonMemory memory = new KingstonMemory();//创建计算机对象Computer c = new Computer();//组装计算机c.setCpu(cpu);c.setHardDisk(hardDisk);c.setMemory(memory);//运行计算机c.run();}
}

测试结果

上面代码可以看到已经组装了一台电脑,但是似乎组装的电脑的cpu只能是Intel的,内存条只能是金士顿的,硬盘只能是希捷的,这对用户肯定是不友好的,用户有了机箱肯定是想按照自己的喜好,选择自己喜欢的配件。

案例2:
根据依赖倒转原则进行改进:

代码我们只需要修改Computer类,让Computer类依赖抽象(各个配件的接口),而不是依赖于各个组件具体的实现类。

类图
cpu接口

/*** @Description: cpu接口*/
public interface Cpu {//运行cpupublic void run();
}

硬盘接口

/*** @Description: 硬盘接口*/
public interface HardDisk {//存储数据public void save(String data);//获取数据public String get();
}

内存条接口

/*** @Description: 内存条接口*/
public interface Memory {public void save();
}

英特尔CPU类(实现CPU接口)

/*** @Description: Intel cpu*/
public class IntelCpu implements Cpu {public void run() {System.out.println("使用Intel处理器");}
}

希捷硬盘类(实现硬盘接口)

/*** 希捷硬盘*/
public class XiJieHardDisk implements HardDisk {//存储数据的方法public void save(String data) {System.out.println("使用希捷硬盘存储数据为:" + data);}//获取数据的方法public String get() {System.out.println("使用希捷希捷硬盘取数据");return "数据";}
}

金士顿内存条类(实现内存条接口)

/*** 金士顿内存条类*/
public class KingstonMemory implements Memory {public void save() {System.out.println("使用金士顿内存条");}
}

电脑类(依赖各个组件的接口)

/*** @ClassName: Computer*/
public class Computer {private HardDisk hardDisk;private Cpu cpu;private Memory memory;public HardDisk getHardDisk() {return hardDisk;}public void setHardDisk(HardDisk hardDisk) {this.hardDisk = hardDisk;}public Cpu getCpu() {return cpu;}public void setCpu(Cpu cpu) {this.cpu = cpu;}public Memory getMemory() {return memory;}public void setMemory(Memory memory) {this.memory = memory;}//运行计算机public void run() {System.out.println("运行计算机");String data = hardDisk.get();System.out.println("从硬盘上获取的数据是:" + data);cpu.run();memory.save();}
}

测试类

/*** 测试类*/
public class ComputerDemo {public static void main(String[] args) {//创建计算机的组件对象HardDisk hardDisk = new XiJieHardDisk();Cpu cpu = new IntelCpu();Memory memory = new KingstonMemory();//创建计算机对象Computer c = new Computer();//组装计算机c.setCpu(cpu);c.setHardDisk(hardDisk);c.setMemory(memory);//运行计算机c.run();}
}

解释说明:

面向对象的开发很好的解决了这个问题,一般情况下抽象的变化概率很小,让用户程序依赖于抽象,实现的细节也依赖于抽象。
即使实现细节不断变动,只要抽象不变,客户程序就不需要变化。这大大降低了客户程序与实现细节的耦合度。
当组装别的品牌组件时,只需要实现对应的接口即可。

结束!!!!!!!


                 人们不愿意相信一个土匪的名字叫牧之

设计原则之依赖倒转原则相关推荐

  1. java依赖倒转原则_设计原则之--依赖倒转原则

    [各位博友晚上好,又到了晚上的这个时间,感谢大家一直对Darren博客的支持,希望这篇文章对你有所帮助: 这几天一直在看设计模式:简单工厂模式,策略模式,单一职责原则,开放 [依赖倒转原则又称依赖倒置 ...

  2. 面向对象编程原则(06)——依赖倒转原则

    版权声明 本文原创作者:谷哥的小弟 作者博客地址:http://blog.csdn.net/lfdfhl 参考资料 <大话设计模式> 作者:程杰 <Java设计模式> 作者:刘 ...

  3. Java里氏转换_里氏代换原则、依赖倒转原则 | 学步园

    里氏代换原则 面向对象设计的重要原则是创建抽象化,并且从抽象化导出具体化,具体化也就是给出不同的实现. 继承关系就是一种从抽象化到具体化的导出. 里氏代换原则:如果对每一个类型为T1的对象o1,都有类 ...

  4. 带你认识六种设计原则(开闭原则、里氏代换原则、依赖倒转原则....)

    前言 1. 设计原则 1.1. 开-闭原则 1.2. 里氏代换原则 1.3. 依赖倒转原则 1.4. 接口隔离原则 1.5. 合成/聚合原则 1.6. 迪米特法则 前言 学习设计模式之前先要了解其中的 ...

  5. Java设计模式之设计的6大原则(开闭原则,里氏代换原则,依赖倒转原则,接口隔离原则,最少知道原则,合成复用原则)

    1. 开闭原则 核心思想:一个对象对外扩展开发,对修改关闭 意思就是:对类的改动是通过增加代码进行的,而不是修改现有的代码. 也就是说软件开发人员一旦写出了可以运行的代码,就不应该去改动它,而是要保证 ...

  6. 三、单一职责原则、开放-封闭原则、依赖倒转原则

    一.单一职责原则 1.定义:就一个类而言,应该仅有一个引起它变化的原因. 2.为什么要?:如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力 ...

  7. 设计模式 学习笔记(2)单一职责原则、开放封闭原则、依赖倒转原则

    (3)单一职责原则 单一职责原则(SRP),就一个类而言,应该仅有一个引起它变化的原因.例如,我们在写一个窗体应用程序,一般都会生成一个Form这样的类,于是我们就把各种各样的代码,像算法.数据库访问 ...

  8. 设计模式——(四)设计模式原则___依赖倒转原则

    一.介绍 依赖倒转原则是指: 1)高层模块不应该依赖低层模块,二者都应该依赖其抽象. 2)抽象不应该依赖细节,细节应该依赖抽象. 3)依赖倒转原则的中心思想是面向接口编程. 4)依赖倒转原则是基于这样 ...

  9. 【设计模式】七大原则之“依赖倒转原则”

    一 基本介绍 依赖倒转原则(Dependence Inversion Principle)是指: 高层模块不应该依赖低层模块,二者都应该依赖其抽象 抽象不应该依赖细节,细节应该依赖抽象 依赖倒转(倒置 ...

最新文章

  1. javascript学习之基本概念
  2. android中怎么网络判断,Android中判断网络是否连接实例详解
  3. MyEclipse连接MySQL时遇到的各种烦人事
  4. java String format占位符
  5. 防止Stack smash的技术
  6. 《SAS编程与数据挖掘商业案例》学习笔记之三
  7. GoogleNet_V3结构(论文复现)
  8. matlab简单分析短时傅里叶变换STFT
  9. 谢谢你,阅读了这篇文章
  10. 剑指offer之二叉搜索树与双向链表
  11. B站还有多久成为天涯
  12. 搜狐老矣,尚能饭否?
  13. linux集群高可用--crm
  14. 如何将域名指向本地服务器
  15. Queen Collisions(分行列模拟)
  16. vue路由详解 --基础
  17. win10远程桌面连接计算机密码错误,访问win10的远程桌面(Remote Desktop)总是凭据或者用户密码错误...
  18. 什么是WAF?WAF的功能有哪些?
  19. Matlab plot绘图颜色详解
  20. 郎平,你回来会毁了中国女排!

热门文章

  1. SAS中的intnx函数
  2. Python解二元一次方程
  3. PMP/CAPM/PgMP/ACP考试报名资格
  4. 移动硬盘数据莫名丢失,如何才能恢复
  5. Android虚拟机运行不了程序,Android程序在Android9.0手机或者虚拟机上运行不了的解决方法...
  6. Android中夜间模式的三种实现方式
  7. android+自定义dns解析,安卓手机玩dnsmasq 搭建自己的DNS服务器
  8. PMS权限管理和鉴权过程
  9. video.js播放m3u8视频
  10. R语言独立样本的 t 检验