1. 依赖倒置原则的定义

  1. 高层模块不应该依赖低层模块,二者都应该依赖其抽象
  2. 抽象不应该依赖细节,细节应该依赖抽象
  3. 依赖倒转的中心思想是面向接口编程
  4. 依赖倒转原则是基于这样的设计理念: 相对于细节的多变性,抽象的东西要稳定的多,以抽象为基础搭建的框架比以细节的框架要稳定的多。在JAVA、C#中,抽象指的是接口或者抽象类,细节就是具体的实现类。
  5. 使用接口或抽象类的目的是指定好的规范,而不涉及任何的具体操作,把展现细节的任务交给他们的实现类去完成。

总之,高层模块,低层模块,细节都应该依赖抽象

依赖倒置具体表现为:

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

2. 为什么是倒转?

一般来说,我们经常为了图方便,把具体类依赖于具体类,也就是所谓的高层模块依赖于低层模块,但是这样是不利于扩展的,违反了设计原则,此时:

而现在根据依赖倒置原则,我们需要将高层模块和低层模块都依赖于接口(或者抽象类)来实现


这里发生了倒置,本来是高层模块依赖于低层模块,低层模块被高层模块依赖,现在是低层模块主动依赖于接口,所以发生了倒置,所以这个原则也称为依赖倒置原则

3. 举例

3.1 第一个例子

摘自于:https://blog.csdn.net/weixin_37505014/article/details/94869450

现在要完成一个Person类接收消息的需求;
方式1:

public class Inversion01 {public static void main(String[] args) {Person person = new Person();person.receive(new Email());}
}
// 完成Person接收消息的功能
class Email {public String getInfo() {return "电子邮件信息: HELLO WORLD";}
}class Person {public void receive(Email email) {System.out.println(email.getInfo());}
}

输出结果:电子邮件信息: HELLO WORLD

这里面Email就是低层模块,而Person是高层模块,高层模块依赖于低层模块,不符合依赖倒置原则,Person类智能接受Email类而不可以接受其他类,要改的话就要每次改代码

该方式很简单的实现了需求,但是有一些问题,我们现在接收的是邮件,如果将来需求变更需要再加上一个可以接收短信的功能,那么我们就需要新增类。同时,Person类也要增加相应的接收方法。

改进:
解决思路,引入一个抽象接口Reveiver,表示接收者,这样Person类与接口发生依赖。因为Email, 短信都属于接收范围,它们各自实现Receiver接口就行了,这样我们就符合依赖倒转原则。

public class Inversion02 {public static void main(String[] args) {Person02 person02 = new Person02();person02.receive(new Email02());person02.receive(new Message());}
}
//先定义一个接口
interface Receiver {String getInfo();
}class Email02 implements Receiver {public String getInfo() {return "电子邮件信息: HELLO WORLD";}
}
//增加短信
class Message implements Receiver {public String getInfo() {return "短信信息: HELLO WORLD";}
}class Person02 {//  这里我们是对接口的依赖,稳定性较好public void receive(Receiver receiver) {System.out.println(receiver.getInfo());}
}

输出结果:电子邮件信息: HELLO WORLD,短信信息: HELLO WORLD

此时,高层模块(Person)和低层模块(Email和Message)都依赖于接口(Receive),符合依赖倒置原则

3.2 第二个例子

摘自:
https://blog.csdn.net/hfreeman2008/article/details/52289571?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control

这个例子里面有个图画错了,IReader和IRead的指向反了,其他没问题

4. 依赖的三种方法

4.1 构造函数传递依赖对象

在类中通过构造函数声明依赖对象,按照依赖注入的说法,这种方式叫做构造函数注入:

构造函数注入:

//小明类
public class XiaoMing implements IReader{private IRead read;//构造函数注入public XiaoMing(IRead read){this.read = read;}//阅读public void read(){read.read();}
}

4.2 Setter方法传递依赖对象

在类中通过Setter方法声明依赖关系,依照依赖注入的说法,这是Setter依赖注入:

//小明类
public class XiaoMing implements IReader{private IRead read;//Setter依赖注入public setRead(IRead read){this.read = read;}//阅读public void read(){read.read();}
}

4.3 接口声明依赖

在接口的方法中声明依赖对象,该方法也叫做接口注入。

public interface IReader{//阅读public void read(IRead read){read.read();}
}
//IReader接口依赖于IRead 接口

5. 依赖倒置原则的经验

依赖倒置原则的本质就是通过抽象(接口或抽象类)使各个类或模块的实现彼此独立,不互相影响,实现模块间的松耦合。我们在项目中使用这个原则要遵循下面的规则:

  • 每个类尽量都有接口或者抽象类,或者抽象类和接口两都具备
  • 变量的表面类型尽量是接口或者抽象类
  • 任何类都不应该从具体类派生
  • 尽量不要覆写基类的方法
  • 如果基类是一个抽象类,而这个方法已经实现了,子类尽量不要覆写。类间依赖的是抽象,覆写了抽象方法,对依赖的稳定性会有一定的影响。

结合里氏替换原则使用

里氏替换原则:父类出现的地方子类就能出现。结合本章我们得出了一个通俗的规则:接口负责定义public属性和方法,并且声明与其他对象的依赖关系。抽象类负责公共构造部分的实现,实现类准确的实现业务逻辑,同时在适当的时候对父类进行细化。

依赖倒置原则是6个设计原则中最难以实现的原则,它是实现开闭原则的重要方法,在项目中,大家只要记住是”面向接口编程”就基本上是抓住了依赖倒置原则的核心了。

设计模式六大原则:依赖倒置原则、为什么、多例子、分析例子、总结相关推荐

  1. 设计模式之禅之六大设计原则-依赖倒置原则

    依赖倒置原则 依赖倒置原则的原始定义是: ● 高层模块不应该依赖低层模块,两者都应该依赖其抽象; ● 抽象不应该依赖细节; ● 细节应该依赖抽象. 那什么是抽象?什么又是细节呢? ---->在J ...

  2. 依赖倒置原则——举例说明Java设计模式中的依赖倒置原则

    依赖倒置原则--举例说明Java设计模式中的依赖倒置原则 一.前言 看官方定义 二.举例说明 2.1 例子介绍(无聊的可看看,着急的请跳过) 2.2 反例 2.1.1 反例1 (1)类图说明 (2)代 ...

  3. 【设计模式】软件设计七大原则 ( 依赖倒置原则 | 代码示例 )

    文章目录 一.依赖倒置原则简介 二.面向实现编程代码示例 ( 反面示例 ) 1.顾客类 2.测试类 三.依赖倒置原则代码示例 ( 推荐示例 | 使用接口方法注入 IGood 实现类 ) 1.顾客类 2 ...

  4. java设计模式之设计原则②依赖倒置原则

    定义: ⑴高层模块不应该依赖低层模块,二者都应该依赖其抽象 ⑵抽象不应该依赖细节,细节应该依赖抽象 ⑶针对接口编程,不要针对实现编程 我们通过抽象包括使用接口或者抽象类可以使各个类或模块的实现彼此独立 ...

  5. 设计模式--6大原则--依赖倒置原则

    依赖倒置原则(Dependence Inversion Principle),简称DIP 定义 High level modules should depend upon low level modu ...

  6. 设计模式系列:依赖倒置原则

    问题由来   问题由来:类A直接依赖类B,假如要将类A改为依赖类C,则必须通过修改类A的代码来达成.这种场景下,类A一般是高层模块,负责复杂的业务逻辑:类B和类C是低层模块,负责基本的原子操作:假如修 ...

  7. Java设计模式6,依赖倒置原则

    目录 一.依赖倒置原则定义 二.违背原则方案 1.项目经理 2.获取平均项目进度 3.获取最慢项目进度 三.依赖倒置原则改善代码 1.获取项目进度接口 2.获取平均项目进度实现类 3.获取最慢项目进度 ...

  8. php 依赖倒置原则,依赖倒置原则 - LieBrother的个人空间 - OSCHINA - 中文开源技术交流社区...

    个人博客原文: 依赖倒置原则 设计模式六大原则之三:依赖倒置原则. 简介 姓名 :依赖倒置原则 英文名 :Dependence Inversion Principle 价值观 :大男子主义的典型代表, ...

  9. 软件设计的七大原则 --开闭原则 里氏替换原则 依赖倒置原则

    在软件开发中,为了提高软件系统的可维护性和可复用性,增加软件的可扩展性和灵活性,程序员要尽量根据 7 条原则来开发程序,从而提高软件开发效率.节约软件开发成本和维护成本. 这 7 种设计原则是软件设计 ...

  10. 设计原则(单一职责原则 开放封闭原则 里氏替换原则 依赖倒置原则 接口隔离原则 迪米特法则)

    设计原则 单一职责原则(SRP) 从三大特性角度看原则: 应用的设计模式: 开放封闭原则(OCP) 从三大特性角度看原则: 应用的设计模式: 里氏替换原则(LSP) 从三大特性角度看原则: 应用的设计 ...

最新文章

  1. python file does not exist_python – os.path.exists()的谎言
  2. 响应微信公众平台公众号菜单单击事件
  3. linux关机方法有哪些?有何区别_Linux关机命令大全:Linux各关机命令之间的区别和用法...
  4. JVM性能优化之CPU负载过高
  5. tensorflow没有代码提示的问题
  6. 基于LDAP的WebLogic虚拟化统一用户权限管理
  7. 互联网+时代企业级应用新生态—— 2016年中国软件技术大会
  8. matplotlib 中设置图形大小
  9. 文本如何垂直居中?多行文本如何实现上下居中?
  10. 为什么说精益管理模式是适合中国企业的管理方法(zt)
  11. mac下使用php cURL方法nginx502错误
  12. IOS菜鸟初学第八篇:接入京东联盟sdk,可打开任意京东的链接
  13. 手写朴素贝叶斯文本分类
  14. VUE项目配置UEditor集成秀米编辑器
  15. MathType如何编辑大三角形符号
  16. 网站必备之简繁切换功能实现
  17. (十五)使用任务通知实现命令行解释器
  18. studio 和mac快捷键
  19. Arduino + RFID 读取 IC 卡 Arduino uno中获得RFID的UID 并通过串口转发RFID卡号
  20. Smali语法学习三

热门文章

  1. nginx代理响应报文体不全解决思路
  2. Python之旅.第十章.mysql
  3. http反向代理调度算法追朔
  4. bootstrap Table API和一些简单使用方法
  5. UITabBarItem如何更改高度
  6. cloudera hbase集群简单思路
  7. 函数式编程学习之路(三)
  8. MYSQL编译参数详解
  9. 漫话:敏捷Scrum研发技术与过程管理实践
  10. TIDB,面向未来的数据库到底是什么?