设计模式——三:依赖倒置原则

1.2.4 依赖倒置原则(Dependency Inversion Principle、DIP)的错误 摘要:依赖倒置原则(Dependency Inversion Principle、DIP)是一个错误的尝试,Robert C. Martin希望将针对接口编程和控制反转两个概念纳入其DIP中,却形成了一个思路混乱的、不知所云的原则。作为正文,不能够喜怒笑骂。草稿抛弃依赖倒置原则将被修改为吐槽版。 1.4.2 抛弃依赖倒置原则(DIP) 在讨论OOD原则时,常常被提到的一个原则叫依赖倒... 阅读详情

什么是依赖倒置原则?

先看看依赖倒置原则的原始定义:

High level modules should not depend upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should depend upon abstractions

翻译一下,包含三层定义:

● 高层模块不应该依赖低层模块,两者都应该依赖其抽象;
● 抽象不应该依赖细节;
● 细节应该依赖抽象。

高层模块和低层模块容易理解,每一个逻辑的实现都是由原子逻辑组成的,不可分割的原子逻辑就是低层模块,原子逻辑的再组装就是高层模块。

抽象和细节呢?在Java语言中,抽象就是指接口或抽象类,两者都是不能直接被实例化的;细节就是实现类,实现接口或继承抽象类而产生的类就是细节,其特点就是可以直接被实例化。

依赖倒置原则在Java语言中的表现就是:
● 模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过 接口或抽象类产生的;
● 接口或抽象类不依赖于实现类;
● 实现类依赖接口或抽象类。

为什么要用依赖倒置原则?

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

以司机驾驶奔驰车为例:

3-1:司机驾驶奔驰车类图


在这里插入图片描述

奔驰车提供一个方法run,代表车辆运行。
奔驰车类:

复制代码
public class Benz { 
 //汽车会跑 
  public void run(){ 
    System.out.println("奔驰汽车开始运行..."); 
   }
}

司机通过调用奔驰车的run方法开动奔驰车.
司机类:

复制代码
public class Driver { 
  //司机的主要职责就是驾驶汽车
   public void drive(Benz benz){ 
   benz.run();
   }
 }

有车,有司机,在Client场景类产生相应的对象.
场景类:

复制代码
public class Client { 
  public static void main(String[] args) { 
    Driver zhangSan = new Driver();
    Benz benz = new Benz(); //张三开奔驰车 
    zhangSan.drive(benz);
   } 
 }

以上实现了司机开车的场景,在功能上是没有问题。

现在新的需求来了,司机不仅要开奔驰车,还要开宝马车。

宝马车类:

复制代码
public class BMW { 
  //宝马车当然也可以开动了
   public void run(){ 
     System.out.println("宝马汽车开始运行..."); 
    }
 }

现在发现问题了,司机没有开动宝马车类的方法,怎么办?给司机类添加开宝马车的方法吗?如果接下来司机要开挖掘机呢?在这里,司机类和奔驰车类之间是紧耦合的关系,其导致的结果就是系统的可维护性大大降低。

这时候就应该引入依赖倒置原则。

3-2:引入依赖倒置原则后的类图

在这里插入图片描述
 

建立两个接口:IDriver和ICar,分别定义了司机和汽车的各个职能,司机实现现drive()方法。

司机接口:

复制代码
public interface IDriver { 
 //老司机,会开车
  public void drive(ICar car); 
}

司机实现类:实现IDriver接口:

复制代码
public class Driver implements IDriver{
  //司机的主要职责就是驾驶汽车 
  public void drive(ICar car){
     car.run();
 } 
}

在IDriver中,通过传入ICar接口实现了抽象之间的依赖关系,Driver实现类也传入了ICar 接口,至于到底是哪个型号的Car,需要在高层模块中声明。

汽车接口及两个实现类:

复制代码
public interface ICar { 
 public void run();
 }

//奔驰汽车类
public class Benz implements ICar{ 
  public void run(){ 
  System.out.println("奔驰汽车开始运行...");
 } 
}

//宝马汽车类
public class BMW implements ICar{ 
  public void run(){ 
    System.out.println("宝马汽车开始运行...");
  } 
}

业务场景类:

复制代码
public class Client { 
  public static void main(String[] args) { 
    IDriver zhangSan = new Driver(); 

    ICar benz = new Benz();
    //张三开奔驰车
     zhangSan.drive(benz); 

    ICar bmw = new BMW(); 
    //张三开宝马车
    zhangSan.drive(bmw);

   } 

}

在新增加低层模块时,只修改了业务场景类,也就是高层模块,对其他低层模块如 Driver类不需要做任何修改,业务就可以运行,把“变更”引起的风险扩散降到最低。

依赖的三种写法

依赖是可以传递的,A对象依赖B对象,B又依赖C,C又依赖D——只要做到抽象依赖,即使是多层的依赖传递也是没有丝毫问题的。

对象的依赖关系有三种方式来传递,如下所示:
 

1.构造函数传递依赖对象

在类中通过构造函数声明依赖对象,按照依赖注入的说法,这种方式叫做构造函数注入,按照这种方式的注入,对IDriver和Driver进行修改。

复制代码
public interface IDriver { 
  //司机就会开车
   public void drive(); 
}

public class Driver implements IDriver{
  private ICar car; 
  //构造函数注入 
  public Driver(ICar _car){ 
    this.car = _car; 
  }
  //司机的主要职责就是驾驶汽车 
  public void drive(){ 
    this.car.run(); 
  } 

}

2、Setter方法传递依赖对象

在抽象中设置Setter方法声明依赖关系,依照依赖注入的说法,这是Setter依赖注入,按照这种方式的注入,对IDriver和Driver进行修改:

复制代码
public interface IDriver { 
  //车辆型号 
  public void setCar(ICar car);
 //是司机就应该会驾驶汽车
  public void drive(); 
}

public class Driver implements IDriver{
  private ICar car; 
  public void setCar(ICar car){ 
  this.car = car; 
  }

 //司机的主要职责就是驾驶汽车
 public void drive(){ 
   this.car.run();
  } 

}

3、接口声明依赖对象

在接口的方法中声明依赖对象,未修改的IDriver和Driver就采用了接口声明依赖的方式,该方法也叫做接口注入。

复制代码
public interface IDriver { 
 //老司机,会开车
  public void drive(ICar car); 
}

public class Driver implements IDriver{
   //司机的主要职责就是驾驶汽车 
   public void drive(ICar car){ 
     car.run(); 
   } 
}

第12章 STM32+BH1750光照传感器+OLED模块显示环境光照强度 相比光敏传感器,它可以直接输出环境光照强度的数值(范围是0~65535lx),非常适合懒人党,各位的传感器买到手后,赶紧跟着文章试试吧! 阅读详情

相关推荐

【接地系统篇】电力系统接地技术详解:从基本原理到实际应用

接地是为电流返回电源提供的一条低阻抗通道。简单来说,就是为故障电流修建一条"安全回家"的路,防止电流通过人体或其他不应带电的部件。接地系统选择原则安全性优先:TN-S系统安全性最高,适合重要场所经济性考虑:TN-C系统成本最低,适合一般工业连续性要求:IT系统供电连续性最好,适合特殊场所灵活性选择:TN-C-S系统兼顾经济与安全,应用最广。

2301_81299416的博客 2235

设计模式—— 三:依赖倒置原则

文章目录什么是依赖倒置原则?为什么要用依赖倒置原则?依赖的三种写法 1.构造函数传递依赖对象2、Setter方法传递依赖对象3、接口声明依赖对象 什么是依赖倒置原则? 先看看依赖倒置原则的原始定义: High level modules should not depend upon low level modules. Both should depend upon abstractions...

三分恶的博客 1691

PHP实战:5分钟搞定SM4国密加密算法集成(附完整代码)

本文提供了一份可直接用于生产环境的PHP SM4国密加密算法集成实战指南。文章详细解析了SM4算法核心,对比了ECB与CBC工作模式,并给出了包含完整代码、密钥管理、数据填充及性能优化的解决方案,帮助开发者快速、安全地在PHP项目中集成国密加密算法。

2a4s6d8f0g的博客 343

设计原则之依赖倒置原则(实例加UML完整例子)

设计原则之依赖倒置原则

atu1111的博客 6351

ESP32S3与ILI9341 LCD屏LVGL移植实战:从零构建嵌入式GUI界面

本文详细介绍了如何在ESP32S3平台上移植LVGL图形库并驱动ILI9341 LCD屏幕,从硬件选型、开发环境配置到显示驱动实现和内存优化。通过实战案例讲解移植过程中的关键步骤和常见问题解决方案,帮助开发者快速构建嵌入式GUI界面。

h9j8k7l6m5n的博客 1098

Theil-Sen Median斜率估计和Mann-Kendall趋势分析:以多年NPP数据为例

一、理论 Theil-Sen Median方法又称为Sen斜率估计,是一种稳健的非参数统计的趋势计算方法。该方法计算效率高,对于测量误差和利群数据不敏感,适用于长时间序列数据的趋势分析。其计算公式为: Mann-Kendall(MK)检验是一种非参数的时间序列趋势性检验方法,其不需要测量值服从正太分布,不受缺失值和异常值的影响,适用于长时间序列数据的趋势显著检验。其过程如下:对 于 序 列Xt = x1,x2,⋯xn,先确定所有对偶值( xi , xj ,...

丑唐的修炼之旅 8万+

设计模式 — 6大设计原则(依赖倒置和接口隔离原则)

设计模式 — 6大设计原则(依赖倒置和接口隔离原则)

weixin_43934626的博客 1914

主成分分析(Principal Component Analysis,PCA)

主成分分析1.主成分分析1.1 降维(Dimensionality Reduction)1.2 均值(Mean)1.3 方差(Variance)1.4 协方差(Covariance)1.5 协方差矩阵(Covariance Matrix)1.6 线性变换(Linear Transformation)1.7 主成分分析(PCA)1.8 PCA和SVD的关系 1.主成分分析 关于PCA的介绍:用最直观的方式告诉你:什么是主成分分析PCA 笔记来源:Principal Component Analysis (PC

一个搬运知识的笨小孩 3232

【设计原则】图解何为依赖倒置

要理解何为倒置,那就先得明确什么是“正向”,可以看到下图代码是自上而下地调用,即高层模块依赖底层模块,这就是正向依赖。而依赖倒置则是使用抽象接口来降低耦合,可以看到箭头是自下而上的,这就是所谓的倒置。这时有人说,如果我箭头调转,抽象类在下,实现类在上,那不就变成正向了?这种观点是不成立的,因为这是 UML 规定抽象类必须在上,实现类在下。

郭昊昀的博客 471

华为od统一考试B卷【宜居星球改造计划】Java&Go 实现

XXX年,人类通过对火星的大气进行宜居改造分析,使得火星已在理论上具备人类宜居的条件,由于技术原因,无法一次性将火星大气全部改造,只能通过局部处理形式,假设将火星待改造的区域为row * column的网格每个网格有3个值,宜居区、可改造区、死亡区,使用YES、NO、NA代替,YES表示该网格已经完成大气改造,NO表示该网格未进行改造,后期可进行改造,NA表示死亡区,不作为判断是否改造完成的宜居,无法穿过 初始化下,该区域可能存在多个宜居区,并且每个宜居区能同时在每个太阳日单位向上下左右四个方向的相邻格子进

MISAYAONE的博客 1万+

网络安全系列-四十三:使用Suricata分析恶意流量pcap文件

本文基于[网络安全系列-三十六:使用Suricata IDS分析pcap文件]和 [网络安全系列-四十二: Suricata之rulesets的激活、更新及动态加载]的基础上,使用suricata针对包含恶意流量的pcap文件进行分析,触发事件告警,并对suricata输出的日志进行逐个分析,让你掌握针对恶意流量的分析步骤,及怎么查看suricata输出的日志。

penriver的博客 2889

设计模式---->依赖倒置原则

依赖倒置原则(Dependence Inversion Principle) 原文地址 一、 依赖倒置原则的定义 依赖倒置原则(Dependence Inversion Principle,简称DIP) 依赖倒置原则的原始定义是: Highlevelmodules should not depend upon low level modules. Both should dependup...

weixin_33797791的博客 340

OpenHarmony AI系列:神经网络处理单元(NPU)驱动架构与实现详解

NPU(Neural Processing Unit,神经网络处理单元)是专门为神经网络计算设计的硬件加速器。在OpenHarmony系统中,NPU驱动是通过NNRT(Neural Network Runtime,神经网络运行时)框架实现的,它作为中间桥梁连接上层AI推理框架和底层NPU硬件,实现AI模型的跨芯片推理计算。

m0_67505153的博客 665

设计模式六大原则(三):依赖倒置原则(Dependence Inversion Principle)

依赖倒置原则(DIP)定义: 高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。 问题由来: 类A直接依赖类B,假如要将类A改为依赖类C,则必须通过修改类A的代码来达成。这种场景下,类A一般是高层模块, 负责复杂的业务逻辑;类B和类C是低层模块,负责基本的原子操作;假如修改类A,会给程序带来不必要的风险。 解决方案: 将类A修改为依赖接口I,...

weixin_30879169的博客 153

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

《设计模式》-原则三:依赖倒置原则(DIP)

  这几天晚上回来都去玩了!没有坚持学习。真的好惭愧! 非常自责 后面一定要坚持 一气呵成 争取每天学一点,把这个学完。   今天主要是看了一下 设计模式中的 原则三: 依赖倒置原则(DIP)   官方是这样定义的:所谓依赖倒置原则指的是是要依据抽象编程,不要依赖与具体。要求客户端依据抽象进行耦合。   意思也就是说抽象不应当依赖于具体,具体应该依赖抽象。要针对接口编程,不要针对具体编程...

weixin_30257433的博客 92

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

[设计模式之禅读书笔记]003_设计模式六大原则(三):依赖倒置原则(Dependence Inversion Principle)...

序言 依赖倒置,这个概念看起来很玄乎,其实很简单。这也是我看所有技术书的心态,在心态上战胜这本书,那么它的内容,也就能很容易理解了。依赖倒置的英文定义如下: High level modules should not depend upon low level modules. Both should depend upon abstractions. Abstractions...

weixin_34138255的博客 126

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

【专题系列】设计模式—— 三:依赖倒置原则

点击上方“Java大数据修炼之道”,右上角选择“设为星标”你想要的优质技术好文第一时间送达!公众号后台回复“资源”,获取独家秘制精品资料来源 |https://www.cnblogs....

hello world! 329

Java 设计模式6大原则之(三):依赖倒置原则

依赖倒置原则(DIP) 定义: 高层模块不应该依赖于底层模块,两者都应该依赖其抽象。抽象不应该依赖细节,细节应该依赖于抽象。是实现开闭原则的基础,其实就是面向接口编程的解释,也就理解了依赖倒置。 详细描述: 在引入抽象层后,系统将具有很好的灵活性,在程序中尽量使用抽象层进行编程,而将具体类写在配置文件中,这样一来,如果系统行为发生变化,只需要对抽象层进行扩展,并修改配置文件,而无须修改原有系统的源代码,在不修改的情况下来扩展系统的功能,满足开闭原则的要求。 在java中,抽象指的是接口或者抽象类,细节

baipenggui_bo 523

设计模式学习三:依赖倒置原则

介绍 依赖倒置原则: 1)高层模块不应该依赖低层模块 2)抽象不应该依赖细节,细节应该依赖抽象 3)依赖倒置的中心思想是面向接口编程 4)依赖倒置的设计理念:相对于细节的多边性,抽象的东西要稳定的多,以抽象为基础搭建的架构比以细节为基础的架构要稳定的多,在java中,抽象指的是接口或抽象类,细节就是具体的实现类。 使用接口或抽象类的目的就是制定好规范,而不涉及任何具体操作,把展现细节的任务交给他...

qq_33366098的博客 125

设计模式之禅阅读笔记三:依赖倒置原则

依赖倒置原则有三层含义: 1.高层模块不应该依赖底层模块,两者都应该依赖其抽象。(模块间依赖都是同各国抽象发生的,其依赖关系应该是通过接口或者抽象类完成的) 2.抽象不应该依赖细节(抽象或者接口不应该依赖实现类) 3.细节应该以来抽象(实现类应该依赖抽象或者接口) 业务场景思考: 1.依赖导致原则在大型开发项目中尤为重要。首先定义好接口或者抽象类,多个人可以对不同层级模块进行同步开发测试。 2.维护,如果业务需求发生变更,针对一个实现类需要实现更多的功能时,我们只需要重新实现一个实现类,不.

weixin_42827269的博客 175

设计模式六大设计原则(三):依赖倒置原则

一、定义 High level modules should not depend upon low level modules.Both should depend upon abstractions.Abstractions should not depend upon details.D...

chuobenggu7592的博客 159

吐槽 依赖倒置原则/DIP

即使yqj2065清楚地知道Robert C. Martin想说的东西,这么胡言乱语的神经病的东西,要逐一地指出其问题,差一点 把我都搞得神经病了。所以,后面的文字乱七八糟的。我留底。

yqj2065的博客 3144

设计模式六大原则例子(四)-- 依赖倒置原则(DIP)例子

之前我们对设计模式的六大原则做了简单归纳,这篇博客是对依赖倒置原则进行的举例说明。 依赖倒置原则的意义DIP是6大原则中最难以实现的原则,它是实现开闭原则的重要途径,DIP没有实现,就别想实现对扩展开放,对修改关闭。在项目中只要记住“面向接口编程”就基本上抓住了DIP的核心 对各种概念进行一个描述: 低层模块:不可分割的原子逻辑,可能会根据业务逻辑经常变化。 高层模块:低层模块的再组合,对低层模块的

yabay2208的博客 1万+

3.六大原则例子-- 依赖倒置原则(DIP)例子

设计模式六大原则例子-- 依赖倒置原则(DIP)例子之前我们对设计模式的六大原则做了简单归纳,这篇博客是对依赖倒置原则进行的举例说明。依赖倒置原则的意义DIP是6大原则中最难以实现的原则,它是实现开闭原则的重要途径,DIP没有实现,就别想实现对扩展开放,对修改关闭。在项目中只要记住“面向接口编程”就基本上抓住了DIP的核心对各种概念进行一个描述:·        低层模块:不可分割的原子逻辑,可能...

郑学炜的技术博客 3771

依赖倒置原则(DIP: Dependency Inversion Principle)

文章目录定义分析理解抽象与实现依赖高层与低层依赖倒置原则总结 定义 DIP在Wikipedia的定义如下。 High level modules should not depend upon low level modules,Both should depend upon abstractions.Abstractions should not depend upon details.Deta...

郝伟老师的博客——大数据、并行计算与人工智能时代 1109

(三)JAVA设计模式中的六大设计原则之依赖倒置原则

所谓依赖倒置原则(Dependence Inversion Principle)就是要依赖于抽象,不要依赖于具体。实现开闭原则的关键是抽象化,并且从抽象化导出具体化实现,如果说开闭原则是面向对象设计的目标的话,那么依赖倒转原则就是面向对象设计的主要手段。

绝对秋香 338
上一篇: 设计模式——二:里氏替换原则
下一篇: 设计模式—— 一:单一职责原则
加班不秃顶
博客等级 码龄7年 1822粉丝 599原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值