依赖倒置原则DIP(Dependence Inversion Principle)

依赖倒置原则的含义

  • 高层模块不能依赖低层模块,二者都应该依赖其抽象。
  • 抽象不应该依赖于细节。
  • 细节应该依赖抽象。

什么是高层模块?低层模块
每一个原子逻辑就是低层模块,原子逻辑再组就是高层模块。
什么是抽象和细节
抽象是抽象类,不可被实例化。
细节是实现类,比如实现的接口或继承抽象类的子类,可以被实例化。

表现在Java语言中就是面向接口编程

  • 模块间的依赖是通过抽象来实现的,具体的实现类之间不能发生直接的依赖。
  • 接口或抽象类不能依赖与实现类。
  • 实现类依赖接口或抽象类。
    ***
    我们假设有三个类,一个为场景类,一个为司机类,一个为奔驰类。通过这三个类我们便可以实现司机开动汽车这个场景。如图

    具体的实现代码如下
    司机类
package des.DIP;
//司机类
public class Driver {//司机驾驶车 紧耦合public void drive(Benze benze){benze.run();}//司机驾驶宝马车 紧耦合public void drive(BMW bmw){bmw.run();}
}

奔驰类

package des.DIP;
//奔驰车
public class Benze {public void run(){System.out.print("奔驰车开始运行...");}
}

场景类

package des.DIP;
//场景类
public class Client {public static void main(String[] args){//创建一个司机Driver zs = new Driver();//创建一个奔驰车Benze benze = new Benze();//司机可以开奔驰车zs.drive(benze);//假设此时增加一个宝马车呢?还要再增加一个方法,并且重新创建//一个还好若是很多呢?难道要在司机类声明很多方法吗?BMW bmw = new BMW();}}
package des.DIP;
//宝马车
public class BMW {//宝马车当然也可以开动public  void run(){System.out.print("宝马车开动...");}
}

程序正常的写法就是如此,但是如果我们考虑下面一个问题,司机并不是只会开着一辆Benze牌的车,假如我们再假如一个BMW(宝马)牌的车,我们传统的做法就是再新建一个类,然后再司机类中再添加一个drive BMW的方法。假如我们要添加无数品牌的汽车呢,难道还要再司机类中添加无数的drive方法吗?他们都有着相同的方法名,只是传入的汽车型号不同。
显然,传统的drive方法的写法,具有紧耦合性,只要车型变更,就不能再使用了。其导致的结果就是系统的可维护性大大降低,可读性也大大降低
*
解决方法
使用依赖倒置原则**

DIP第一种方法 接口注入法

建立两个接口,IDriver和ICar

此时业务的场景类就可以改写成如下

package des.DIP;public class Client1 {public static void main(String[] args){//创建一个司机/*** 此处明确两个概念:* IDriver 叫做表面类型, Driver1 叫做实际类型  或称抽象类型和实际类型** 此后所有的操作均是对抽象接口的操作,具体屏蔽了细节*/IDriver ds = new Driver1();ICar c = new Bmw1();ds.drive(c);}
}

表面类型和实际类型: IDriver 叫做表面类型, Driver1 叫做实际类型 或称抽象类型和实际类型

下面是接口类和实现类参考代码:

package des.DIP;
//司机接口
public interface IDriver {//司机可以驾驶汽车,什么汽车不用管即抽象类(松耦合)public void drive(ICar car);
}
package des.DIP;
//抽象汽车类
public interface ICar {//汽车启动public void run();
}
package des.DIP;public class Driver1 implements  IDriver {@Overridepublic void drive(ICar car) {car.run();}
}
package des.DIP;public class Bmw1 implements  ICar {@Overridepublic void run() {System.out.print("宝马车开始运行...");}
}
package des.DIP;public class Benze1 implements  ICar {@Overridepublic void run() {System.out.print("奔驰车开始运行...");}
}

假设我们项目中有两个类是依赖关系,此时我们只需要定义两个抽象类就可以独立开发了。

DIP第二种方法 构造函数传递依赖对象

package des.DIP;
//司机接口
public interface IDriver {//司机可以驾驶汽车,什么汽车不用管即抽象类(松耦合)public void drive(ICar car);/***************************/public void drive();
}
package des.DIP;public class Driver1 implements  IDriver {/******************************************************/private ICar car;//构造函数注入public Driver1(ICar _car){this.car = _car;}@Overridepublic void drive() {this.car.run();}/******************************************************/@Overridepublic void drive(ICar car) {car.run();}}
IDriver ds1 = new Driver1(new Bmw1());
ds.run();

运行结果

构造函数依赖注入理解图示


DIP第三种方法 setter方法传递依赖对象




代码参考

package des.DIP;
//司机接口
public interface IDriver {public void setCar(ICar car);public void drive();}
package des.DIP;
public class Driver1 implements  IDriver {/******************************************************/private ICar car;@Overridepublic void setCar(ICar car) {this.car.run();}@Overridepublic void drive() {this.car.run();}}
package des.DIP;public class Client1 {public static void main(String[] args){IDriver ds1 = new Driver1();ds1.setCar(new Bmw1());ds1.drive();}
}

DIP总结

  • DIP本质就是通过抽象类来实现彼此独立,互不影响
  • 依赖倒置的核心是面向接口编程,即上面的第一种方法。
  • 依赖倒置的具体使用规则如下
    • 每个类尽量有接口或抽象类,或者二者都有。
    • 变量的表面类型尽量是接口或抽象类。
    • 任何类不应该从具体类派生。
    • 尽量不要覆写基类的方法。
    • 结合里氏替换原则进行。
  • 依赖倒置需要审时度势,而不是永远抓住这个原则不放,任何一个原则的优点都是有限的。

对于倒置的理解

从反面讲:什么是正置?如上例子,我们开什么型号的车,就依赖什么样型号的车。不存在什么抽象类与接口,直接单独建立即可,需要什么建立什么。但是依赖倒置?就是对车进行抽象,抽象出类和接口,建立抽象间的依赖。

转载于:https://www.cnblogs.com/quinntian/p/10739188.html

六大设计原则(三)DIP依赖倒置原则相关推荐

  1. C#软件设计——小话设计模式原则之:依赖倒置原则DIP

    前言:很久之前就想动笔总结下关于软件设计的一些原则,或者说是设计模式的一些原则,奈何被各种bootstrap组件所吸引,一直抽不开身.群里面有朋友问博主是否改行做前端了,呵呵,其实博主是想做" ...

  2. 面象对象设计6大原则之五:依赖倒置原则

    转载自 面象对象设计6大原则之五:依赖倒置原则 依赖倒置原则(DIP),The Dependency Inversion Principle 定义 1.高层模块不应该依赖低层模块,两都应该依赖于抽象. ...

  3. 设计模式原则之六:依赖倒置原则

    依赖倒置原则(简称DIP),的本质骑士就是通过抽象(抽象类或接口)使各个类或模块的实现彼此独立,不相互影响,实现模块间的松耦合.但是这个原则也是6个设计原则中最难以实现的了,如果没有实现这个原则,那么 ...

  4. 软件架构设计原则-DIP依赖倒置原则

    一.什么是依赖倒转原则 依赖倒转(Dependence Inversion Principle ): 1.抽象不应该依赖于细节,细节应该依赖于抽象. 2.高层模块不依赖底层模块,两者都依赖抽象. 二. ...

  5. [白话解说]DIP 依赖倒置原则

    题记:忽然觉得一些解释概念的文章解释有些故弄玄虚,准备跟着自己的阅读情况白话翻译一些. 依赖倒置(Dependence Inversion Principle) 高级模块不应当依赖于低级模块.它们都应 ...

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

    1. 依赖倒置原则的定义 高层模块不应该依赖低层模块,二者都应该依赖其抽象 抽象不应该依赖细节,细节应该依赖抽象 依赖倒转的中心思想是面向接口编程 依赖倒转原则是基于这样的设计理念: 相对于细节的多变 ...

  7. 软件设计原则之里氏替换原则、依赖倒置原则

    系列文章目录 软件设计原则之单一职责原则.开闭原则 软件设计原则之里氏替换原则.依赖倒置原则 软件设计原则之接口隔离原则.合成复用原则.迪米特原则 文章目录 系列文章目录 一.里氏替换原则 什么是里氏 ...

  8. 面向对象设计原则-03依赖倒置原则

    面向对象设计原则-03依赖倒置原则 依赖倒置原则的定义 依赖倒置原则(Dependence Inversion Principle,DIP)是 Object Mentor 公司总裁罗伯特·马丁(Rob ...

  9. 依赖倒置原则——面向对象设计原则

    前两节我们详细介绍了面向对象设计原则中的开闭原则和里氏替换原则,在本节中我们来介绍依赖倒置原则. 依赖倒置原则的定义 依赖倒置原则(Dependence Inversion Principle,DIP ...

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

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

最新文章

  1. RDKit | 基于随机森林的化合物活性二分类模型
  2. APACHE 安装出错 configure: error: Cannot use an external APR with the bundled APR-util
  3. 十一.python面向对象(接口)abstractmethod,ABCMeta
  4. Git的使用-将本地项目上传至Github/Github下载代码至本地-MAC
  5. H3C S5500核心交换机策略路由调度流量到不同的路由设备
  6. Linux运维实战之DNS的高级配置(转发器、视图等)
  7. MVC阻止用户注入JavaScript代码或者Html标记
  8. java 面向对象之内存管理
  9. 阿里舆情︱舆情热词分析架构简述(Demo学习)
  10. NAACL2021论文:UniDrop:一种简单而有效的Transformer提升技术
  11. X9C102PIZ数字电位器-中文
  12. Windows 10 下生成 ssh 密钥
  13. oracle. 设置参数 sid,更改Oracle数据库的SID
  14. 图片展示(上面一个大图下面四个小图)
  15. PhalApi+Gearman,接口MQ异步队列任务的完整开发教程
  16. 生物化学 电阻抗成像OpenEIT,Dbar算法,数据集等(暂记)
  17. 互联网日报 | 7月1日 星期四 | 滴滴正式登陆纽交所;奈雪的茶上市首日破发;2021年铁路暑运今日正式启动...
  18. Google Payments?
  19. Elasticsearch:Data streams(三)
  20. 生活小窍门小全-热爱生活,就收藏它吧!

热门文章

  1. Java Web之MySQL在项目中的使用
  2. Android 程序调试
  3. 软件众包,哪个数据库好
  4. csharp:SQLite and Access using C# code read data
  5. Delphi单元文件引用名称问题
  6. Bash脚本15分钟进阶教程-转
  7. 知乎:国家何时整治程序员的高效现象?
  8. 再见!收费的 XShell,我改用国产良心工具!
  9. LinkedList 真的是查找慢增删快?刷新你的认知!
  10. 面试官:给我说说你对Java GC机制的理解?