设计模式—依赖倒置原则(DIP)

1.概念

依赖倒置原则(Dependence Inversion Principle)是程序要依赖于抽象接口,不要依赖于具体实现。简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合。

通俗的讲:

  1. 要面向抽象编程,而不是面向细节编程;

  2. 高层模块不应该依赖底层模块,二者应该通过抽象依赖,而不是依赖细节;

  3. 抽象不应该依赖于具体,具体应该依赖于抽象。

2.案例分析

需求:我们要开发一套自动驾驶系统,只要在汽车上安装该系统就可以实现自动驾驶,该系统目前只支持在福特和本田车上使用。

优化前版本(不满足依赖倒置原则):

/// <summary>/// 福特车/// </summary>public class FordCar{public void Run(){Console.WriteLine("福特开始启动了");}public void Turn(){Console.WriteLine("福特开始转弯了");}public void Stop(){Console.WriteLine("福特开始停车了");}}/// <summary>/// 本田车/// </summary>public class HondaCar{public void Run(){Console.WriteLine("本田开始启动了");}public void Turn(){Console.WriteLine("本田开始转弯了");}public void Stop(){Console.WriteLine("本田开始停车了");}}/// <summary>/// 自动驾驶/// </summary>public class AutoSystem{private HondaCar hcar = new HondaCar();private FordCar fcar = new FordCar();private CarType type;public AutoSystem(CarType type){this.type = type;}/// <summary>/// 启动/// </summary>public void RunCar(){if (type == CarType.Ford){fcar.Run();}else{hcar.Run();}}/// <summary>/// 转弯/// </summary>public void TurnCar(){if (type == CarType.Ford){fcar.Turn();}else{hcar.Turn();}}/// <summary>/// 停车/// </summary>public void StopCar(){if (type == CarType.Ford){fcar.Stop();}else{hcar.Stop();}}public enum CarType : int{[Description("福特车")]Ford = 0,[Description("本田车")]Honda = 1,};}{//DIP:依赖倒置原则//福特车AutoSystem fordAutoSystem = new AutoSystem(CarType.Ford);fordAutoSystem.RunCar();fordAutoSystem.TurnCar();fordAutoSystem.StopCar();//本田车AutoSystem hondaAutoSystem = new AutoSystem(CarType.Honda);hondaAutoSystem.RunCar();hondaAutoSystem.TurnCar();hondaAutoSystem.StopCar();}

代码分析:

上面的程序确实能够实现针对Ford和Honda车的无人驾驶,但是在实际的生成场景中需求是不断变化的,比如我们现在又增加了一个新的合作伙伴:宝马车,那我们就需要新定义一个宝马车的实现类,以及对应的枚举CarType和上层的AutoSystem类都需要跟着修改,当随着越来越多的车企加入我们,那我们当前的设计就会变得僵化、脆弱。

如何优化?

导致上面所述问题的一个原因是:含有高层策略的utoSystem模块,依赖于它所控制的低层的具体细节的模块:HondaCar和FordCar。如果我们能够找到一种方法使AutoSystem模块独立于它所控制的具体细节,那么我们就可以自由地复用它了。我们就可以用这个模块来生成其它的程序,使得系统能够用在需要的汽车上。毋庸置疑那就该我们的依赖倒置原则出场了。

优化后的版本(满足依赖倒置原则):

/// <summary>/// 接口层/// </summary>public interface ICar{void Run();void Turn();void Stop();}/// <summary>/// 福特车/// </summary>public class FordCarDIP : ICar{public void Run(){Console.WriteLine("福特开始启动了");}public void Turn(){Console.WriteLine("福特开始转弯了");}public void Stop(){Console.WriteLine("福特开始停车了");}}/// <summary>/// 本田车/// </summary>public class HondaCarDIP : ICar{public void Run(){Console.WriteLine("本田开始启动了");}public void Turn(){Console.WriteLine("本田开始转弯了");}public void Stop(){Console.WriteLine("本田开始停车了");}}/// <summary>/// 自动驾驶/// </summary>public class AutoSystemDIP{private ICar icar;public AutoSystemDIP(ICar icar){this.icar = icar;}/// <summary>/// 启动/// </summary>public void RunCar(){icar.Run();}/// <summary>/// 拐弯/// </summary>public void TurnCar(){icar.Turn();}/// <summary>/// 停车/// </summary>public void StopCar(){icar.Stop();}}{//DIP:依赖倒置原则//福特车ICar car = new FordCarDIP();AutoSystemDIP fordAutoSystem = new AutoSystemDIP(car);fordAutoSystem.RunCar();fordAutoSystem.TurnCar();fordAutoSystem.StopCar();//本田车car = new HondaCarDIP();AutoSystemDIP hondaAutoSystem = new AutoSystemDIP(car);hondaAutoSystem.RunCar();hondaAutoSystem.TurnCar();hondaAutoSystem.StopCar();}

代码分析:

AutoSystem系统依赖于ICar 这个抽象,而与具体的实现细节HondaCar、FordCar无关,所以实现细节的变化不会影响AutoSystem。对于实现细节只要实现ICar 即可,即实现细节依赖于ICar 抽象。

3.优缺点

优点:

  1. 降低类与类之间的耦合性;

  2. 增强系统的稳定性;

  3. 提高代码的可读性和维护性;

  4. 降低修改代码带来的风险;

缺点:

除了抽象难度大点、需要对功能业务理解透彻以外,几乎无缺点,依赖倒置还是我们开发中使用比较频繁的一个原则。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/171968.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot校验List失效解决方法

文章目录 SpringBoot校验List失效解决方法附&#xff1a;校验基本数据类型和String类型的方法参数时也需要在类上加Validated SpringBoot校验List失效解决方法 失效场景示例代码&#xff1a; RestController RequestMapping("/v1/jx/flowSummary") Slf4j public cl…

抖音小店开店指南:流程、准备和营销策略一站解析

抖音小店已成为一个热门的社交电商平台&#xff0c;为商家提供了一个快速、方便、低成本的开店通道。下面四川不若与众将介绍抖音小店开店的流程和需要准备的工作&#xff0c;帮助商家顺利开启自己的电商之路。 一、开店准备工作&#xff1a; 1. 产品准备&#xff1a;确定出售…

Java王者荣耀

一、创建项目 二、代码 package com.sxt;import javax.swing.*; import java.awt.*;public class Background extends GameObject {public Background(GameFrame gameFrame) {super(gameFrame);// TODO Auto-generated constructor stub}Image bg Toolkit.getDefaultToolkit(…

Mac 最佳使用指南

如何在macOS系统安装根证书mac Terminal config proxy 【mac 终端配置代理】iPhone 安装 iOS 17公测版&#xff08;Public Beta)macOS 最佳命令行客户端&#xff1a;iTermMac 配置与 Linux 互信Mac mini 外接移动硬盘无法写入或者无法显示的解决方法如何在 macOS 美化 iterm2 &…

数据库基础教程之数据库的创建(二)

双击打开Navicat,点击:文件-》新建连接-》PostgreSQL 在下图新建连接中输入各参数,然后点击:连接测试,连接成功后再点击确定。 创建数据表   3.1 方法1   3.1.1.双击你的数据库-》双击public-》双击选中表-》右键-》新建表-》常规 3.1.2.设置字段信息   双击选中创建…

C++ vector迭代器失效

STL中vector迭代器失效常见错误写法示例 最近在看STL容器失效的例子&#xff0c;涉及到vector数组迭代器失效的问题&#xff0c;如果不注意使用&#xff0c;很容易出现问题&#xff0c;我们先来看一下一个简单的示例程序&#xff0c;在数组nums中删除大于50的元素&#xff0c;…

【方块消消乐】方块消除游戏-微信小程序开发流程详解

有做过俄罗斯方块游戏小程序的经验&#xff0c;这次有做了一个消灭方块的游戏&#xff0c;实现过程很顺利&#xff0c;游戏看着和之前做的俄罗斯方块游戏很像&#xff0c;这里调整了玩法&#xff0c;试玩感觉还可以&#xff0c;接下来给大家讲一讲消灭方块游戏开发过程。 俄罗斯…

(离散数学)命题逻辑推理一:直接推理

P说明这一行是前提&#xff0c;T说明这一行是结论 &#xff0c;I说明该结论是由推导而来&#xff0c;E说明该结论是由化简而来&#xff0c;括号里的数字是推导这一结论需要的条件序号。 这种写法只是将重言蕴含的论证的思路进行了梳理 &#xff0c;前件为真则后件为真、后件为假…

【深度学习】DAMO-YOLO,阿里,701类通用检测模型,目标检测

https://github.com/tinyvision/DAMO-YOLO/blob/master/README_cn.md DAMO-YOLO是由阿里巴巴达摩院智能计算实验室TinyML团队开发的一个兼顾速度与精度的目标检测框架,其效果超越了目前的一众YOLO系列方法&#xff0c;在实现SOTA的同时&#xff0c;保持了很高的推理速度。DAMO…

Linux 面试题(一)

目录 1、绝对路径用什么符号表示&#xff1f;当前目录、上层目录用什么表示&#xff1f;主目录用什么表示? 切换目录用什么命令&#xff1f; 2、怎么查看当前进程&#xff1f;怎么执行退出&#xff1f;怎么查看当前路径&#xff1f; 3、怎么清屏&#xff1f;怎么退出当前命…

rdf-file:分布式环境下的文件处理

一&#xff1a;数据量大了以后&#xff0c;单机解析或者生成文件的效率就很低&#xff0c;需要通过集群处理 机构过来的文件&#xff1a;我们先对文件进行分片&#xff0c;在利用集群集群处理分片文件。给机构文件&#xff1a;分库分表数据&#xff0c;每个分表生成一个分片文…

VMware安装部署kail镜像服务器【详细包含百度云盘镜像】

VMware安装部署kail镜像服务器【详细包含百度云盘镜像】 kail是一个很好玩的操作系统&#xff0c;不多说了哈 下载kail镜像 kail官网:https://www.kali.org/get-kali/#kali-platforms 百度云盘下载&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1PRjoP_1v8DEZ7-dA_…

基于51单片机的智能垃圾桶硬件设计

**单片机设计介绍&#xff0c; 基于51单片机的智能垃圾桶硬件设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于51单片机的智能垃圾桶设计旨在通过传感器和控制电路实现智能化的垃圾桶功能。下面是一个简要的硬件设计介绍&…

51代码审计-PHP框架MVC类上传断点调试

知识点1&#xff0c;文件上传漏洞挖掘 搜索关键字$_FILES phpmvc架构 MVC模式&#xff08;Model-View-Controller&#xff09;是软件工程中的一种软件架构模式。 MVC把软件系统分为三个基本部分&#xff1a;模型&#xff08;Model&#xff09;、视图&#xff08;View&#…

Redis面试题:Redis的数据淘汰策略有哪些?

目录 面试官&#xff1a;Redis的数据淘汰策略有哪些 ? 面试官&#xff1a;数据库有1000万数据 ,Redis只能缓存20w数据, 如何保证Redis中的数据都是热点数据 ? 面试官&#xff1a;Redis的内存用完了会发生什么&#xff1f; 面试官&#xff1a;Redis的数据淘汰策略有哪些 ? …

C++ day36 贪心算法 无重叠区间 划分字母区间 合并区间

题目1&#xff1a;435 无重叠区间 题目链接&#xff1a;无重叠区间 对题目的理解 移除数组中的元素&#xff0c;使得区间互不重叠&#xff0c;保证移除的元素数量最少&#xff0c;数组中至少包含一个元素 贪心算法 局部最优&#xff0c;使得重叠区间的个数最大&#xff0c…

GCPS—20型工程钻机的设计自动摊铺机的设计机械设计

wx供重浩&#xff1a;创享日记 对话框发送&#xff1a;摊铺机 获取完整论文报告工程源文件 摊铺机是一种复合式多功能摊铺机&#xff0c;为适应我国深基础和连续墙以及水利、纺织的发展与需要&#xff0c;结合大口径摊铺机灌注桩和地下连续墙施工的特点&#xff0c;为解决在复…

【数据结构】树的概念以及二叉树

目录 1 树概念及结构 1.1 树的概念 1.3 树的存储 2 二叉树的概念及结构 2.1 概念 2.2 特殊的二叉树 2.3 二叉树的性质 2.4 二叉树的存储结构 1 树概念及结构 1.1 树的概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组…

Java进阶(第二期):package 包 抽象类和抽象方法 接口的实现 多态的实现 综合继承、接口、多态的使用。

2023年11月26日20:11:11 文章目录 Java进阶&#xff08;第二期&#xff09;一、package包的概念二、抽象类和抽象方法(abstract)2.1 使用2.1 抽象类注意事项 三、接口3.1 接口的定义格式3.2 接口成员特点3.3 类和接口的关系3.4 接口和抽象类的对比 四、多态4.1 多态的前提条件4…

Sentry介绍与使用 - Issues模块

这篇文章是我在公司做 Sentry 相关分享的演讲稿。 大家好&#xff0c;现在由我来讲解 Sentry 的 Issues &#xff08;问题&#xff09;模块。我会分为三个部分来讲&#xff0c;首先我会介绍 Sentry 一些重要的概念&#xff0c;然后讲一下 Issues 的基本使用方式&#xff0c;最后…