【设计模式】六大原则之依赖倒置原则(Dependency Inversion Principle,‌DIP)

news2025/1/11 18:50:02

设计模式是对相关问题提出的解决方案。

一般而言,一个模式有四个基本要素:

  1. 模式名称 (pattern name) 一个助记名,它用一两个词语来描述模式问题、解决方案和效果。
  2. 问题(problem)描述了应该在何时使用模式,解释了问题存在的前因后果。
  3. 解决方案(solution)描述了设计的组成成分,它们之间的相互关系以及各自的职责和协作方式。
  4. 效果(consequence)描述了模式应用的效果以及使用模式应权衡的问题。

在这里插入图片描述

定义

依赖倒置原则Dependency Inversion Principle,‌DIP)是编程开发中的一个重要原则,具体指抽象不应该依赖于具体类,具体类应当依赖于抽象
换言之,要针对接口编程,而不是针对实现编程,旨在降低模块间的耦合度,提高系统的可维护性和稳定性。

核心思想

DIP的核心思想是:高层模块不应该依赖低层模块,两者都应该依赖抽象。抽象不应该依赖细节,细节应该依赖抽象。这意味着在编程时,我们应该针对抽象进行编程,而不是针对具体的实现进行编程。这样可以降低客户与实现模块间的耦合,提高系统的稳定性和可重用性。‌

要求

依赖倒转原则要求我们在程序代码中传递参数时或在关联关系中,尽量引用层次高的抽象层类,即使用接口和抽象类进行变量类型声明、参数类型声明、方法返回类型声明,以及数据类型的转换等,而不要用具体类来做这些事情。为了确保该原则的应用,一个具体类应当只实现接口或抽象类中声明过的方法,而不要给出多余的方法,否则将无法调用到在子类中增加的新方法。

优点

采用依赖倒置原则有以下优点:

  • 减少类间的耦合性:通过依赖抽象而不是具体实现,可以降低模块之间的耦合度,使得系统更加灵活和可扩展。‌
  • 提高系统的稳定性:通过依赖抽象,可以减少因低层模块变更对高层模块的影响,从而提高系统的稳定性。
  • 提高代码的可读性和可维护性:降低模块间的直接依赖关系,使得代码更加清晰和易于维护。
    在实际应用中,DIP可以通过以下方式实现:

高层模块和低层模块都依赖于抽象:通过定义接口或抽象类,高层模块和低层模块都依赖于这些抽象,而不是直接依赖于对方。这样可以降低模块间的耦合度,提高系统的可维护性和可扩展性。‌
使用依赖注入:依赖注入是一种具体实现方法,通过将依赖关系交给外部进行注入,可以进一步降低模块间的耦合度,使得系统更加灵活和可扩展。‌

简单案例

  1. 定义抽象接口
    首先定义一个抽象接口或基类,这个接口或基类定义了一组方法,这些方法是所有具体实现都需要遵循的契约。
// 抽象接口
class MessageSender {
  send(message) {
    throw new Error('Method "send" must be implemented.');
  }
}
  1. 创建具体实现
    然后创建具体的类来实现上述抽象接口。
// 具体实现
class EmailSender extends MessageSender {
  send(message) {
    console.log(`Sending email: ${message}`);
  }
}

class SmsSender extends MessageSender {
  send(message) {
    console.log(`Sending SMS: ${message}`);
  }
}
  1. 使用依赖注入
    接下来,在需要发送消息的业务逻辑中,我们不直接创建EmailSender或SmsSender实例,而是通过构造函数或setter方法注入这些依赖。
class NotificationService {
  constructor(sender) {
    this.sender = sender;
  }

  notify(message) {
    this.sender.send(message);
  }
}
  1. 使用示例
    现在我们可以根据不同的需求来注入不同的消息发送器。
const emailSender = new EmailSender();
const smsSender = new SmsSender();

const notificationService = new NotificationService(emailSender);

notificationService.notify('Welcome to our service!'); // 输出: Sending email: Welcome to our service!

// 更换发送方式
notificationService.sender = smsSender;

notificationService.notify('Welcome to our service!'); // 输出: Sending SMS: Welcome to our service!

总结:依赖倒置原则

  1. 高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象。
  2. 抽象不应该依赖于具体,具体应该依赖于抽象。

具体使用案例 https://segmentfault.com/a/1190000012929864

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

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

相关文章

Unity中对Spine动画播放、暂停、事件处理管理类

Unity中对Spine动画播放、暂停、事件处理管理类 介绍Spine的事件处理动画师制作沟通Unity前端使用事件 Unity中动画播放Unity中动画暂定和继续Unity中停止动画Unity中动画转向Unity中获取骨骼和设置插槽附件完整管理类分享总结 介绍 最近在做设计spine动画的抖音小程序&#x…

RecyclerView的缓存机制(面试常客)

在构建滚动列表时,我们常首选RecyclerView,出于它优秀的缓存复用机制。 核心机制 RecyclerView的缓存机制又称回收复用机制,RecyclerView构建列表视图分为以下三步: 第一步的创建ViewHolder是RecyclerView构建视图时最耗时的操作…

鸿蒙(API 12 Beta3版)【使用通话设备切换组件】使用投播组件

基本概念 系统不再提供音频输出设备切换的API,如果需要应用内切换音频输出设备,请实现AVCastPicker组件,相关参数可参考[ohos.multimedia.avCastPicker]和 [ohos.multimedia.avCastPickerParam]。 本文将主要介绍AVCastPicker组件接入&…

【论文笔记】:PVswin-YOLOv8s:基于无人机的行人和车辆检测,使用改进的YOLOv8在智能城市中进行交通管理

摘要 在智慧城市中,有效的交通拥堵管理取决于熟练的行人和车辆检测。无人机 (UAV) 提供了一种具有移动性、成本效益和宽视野的解决方案,然而,优化识别模型对于克服小型和遮挡物体带来的挑战至关重要。为了解决这些问题…

推出 SAM 2:适用于视频和图像的下一代 Meta Segment Anything 模型

继图像元分割模型(SAM) 取得成功之后,我们发布了SAM 2,这是一个用于在图像和视频中实时提示对象分割的统一模型,可实现最先进的性能。 为了秉承我们的开放科学方针,我们通过宽松的 Apache 2.0 许可证共享代码和模型权重。 我们还…

嵌入式linux系统镜像制作day2

点击上方"蓝字"关注我们 01、前言 嵌入式linux系统镜像制作day1这一节先了解,后面实操 02、Yocto项目快速启动 Yocto项目通过OpenEmbedded构建系统为各种平台(包括x86-64和仿真平台)提供了一个针对ARM、MIPS、PowerPC和x86架构的开源开发环境。您可以使用Yocto项…

WebDeveloper:1靶机渗透测试

一、靶机下载地址 https://www.vulnhub.com/entry/web-developer-1,288/ 二、信息收集 1、主机发现 # 使用命令 nmap 192.168.145.0/24 -sn | grep -B 2 "00:0C:29:54:22:E9" 2、端口扫描 # 使用命令 nmap 192.168.145.216 -p- -sV 3、指纹识别 # 使用命令 wha…

【SpringCloud】什么是MQ

RabbitMQ 1.什么是MQ 1.1 同步和异步通信 微服务间通讯有同步和异步两种方式: 同步通讯:就例如打电话一样,需要实时响应异步通讯:就例如发邮件一样,不需要马上回复 1.1.1同步通讯 Feign的远程调用就属于同步通讯…

【数据分析】描述性统计分析 - 直方图

一、什么是直方图 由一批长方形构成,通过长方形的面积或高度来代表对应组在数据中所占的比例。用长方形的面积代表对应组的频数与组距的比时,则称为频率分布直方图;当用长方形的高代表对应组的频数时,则称为频数分布直方图。但严格统计意义上…

WT32-ETH01开发板模块,启明云端物联网方案,乐鑫ESP32多样化开发应用

在物联网(IoT)的浪潮中,无线Wi-Fi模块作为连接传统硬件与现代智能网络的桥梁,正逐渐成为智能家居和设备通信不可或缺的一部分。Wi-Fi模块也被称为串口Wi-Fi模块,是一种嵌入式模块,它能够将串口或TTL电平信号转换为符合Wi-Fi无线网…

普元EOS-多数据源时业务数据库初始化

1 问题 EOS开发应用的时候,可以采用多数据源。 项目启动的是时候报错如下: 2024-08-14 16:03:56.105 ERROR [EOS-DEMO-SYS,EOSLOWCODE,default,cuipengyu:EOSLOWCODE:28015,,,,] 28960 --- [Timer-0] c.p.g.a.a.m.RdcloudStatisticsThread : User…

66_1JSON【浏览器中处理JSON、Java中处理JSON(FastJSON、Jackson)】、Java中的bean

JSON 概念 JSON:JavaScript Object Notation是一种表示对象的方式 基于JavaScript语言的轻量级的数据交换格式;(即:用来传输数据的一种格式) 现在传输数据的方式更多是采用json的格式,渐渐代替了XML JSON的数据表示 JSON采用名值…

封装一个细粒度的限流器

文章目录 原因限流对象限流后的做法怎么确定限流阈值观测业务性能数据压测借鉴链路上的其他服务手动计算 四种静态限流算法令牌桶漏桶固定窗口与滑动窗口 手写限流算法令牌桶漏桶固定窗口滑动窗口 分布式限流的具体实现 原因 尽管云原生网关里有统一入口的限流(根据…

股指期货套期保值中的展期管理有哪些?

在复杂的金融市场环境中,展期作为一种重要的风险管理工具,被广泛应用于期货交易中,特别是当投资者需要对长期资产进行套期保值时。展期的核心思想在于,通过连续替换高流动性的近月期货合约来替代流动性较差的远月合约,…

untiy有渲染线程和逻辑线程嘛

之前我也这么认为,其实unity引擎是单线程的,当然后续的jobs不在考虑范围内 如果你在一个awake 或者 start方法中 延时,是会卡住主线程的 比如 其实游戏引擎有一个基础简单理解,那就是不断的进行一个循环,在这个周期循…

网络分段如何增强 OT 网络的可见性

防火墙在保护运营技术(OT) 网络和系统方面发挥什么作用? 很多人会说,防火墙是一种防御机制,用于保护该环境免受 IT 和外界的影响。对于负责该关键系统正常运行的操作员来说,防火墙是阻止他人进入的外围保护。它也是需要从 OT 系统…

Unity Render Streaming项目实践经验

UnityRenderStreaming项目 项目github地址见上,我使用项目的3.1.0-exp.7版本、Unity 2023.1.0版本、windows11运行。 1下载项目包 2在Unity Hub中打开RenderStreaming~文件夹 3在package manager中导入com.unity.renderstreaming package 因为已经下载过了就选择install pa…

Linux shell编程学习笔记71: sort 命令——构造有序世界

0 前言 在大数据时代,我们面对和使用大量数据,如果数据是有序的,无疑是有益的。 在Linux中,我们可以使用 sort 命令来构造一个有序的空间。 1 sort命令 的功能、格式和选项说明 我们可以使用命令sort --help来获取帮助信息。 …

Spark MLlib 特征工程(下)

Spark MLlib 特征工程(下) 前面我们提到,典型的特征工程包含如下几个环节,即预处理、特征选择、归一化、离散化、Embedding 和向量计算,如下图所示。 在上一讲,我们着重讲解了其中的前 3 个环节,也就是预处理、特征选…

Memecoin的火爆与AMM在Solana上的主导地位

随着Solana区块链的高速发展,尤其是近年来Memecoin市场的崛起,AMM(自动做市商)逐渐成为Solana去中心化交易所(DEX)的主导交易模式。尽管Solana以其高效性能能够支持每秒数千笔交易,足以让中心化…