深入理解设计原则之依赖反转原则(DIP)

news2024/12/23 2:31:51

系列文章目录

C++高性能优化编程系列
深入理解设计原则系列
深入理解设计模式系列
高级C++并发线程编程

DIP:依赖反转原则

  • 系列文章目录
  • 1、依赖反转原则的定义和解读
  • 2、稳定的抽象层
  • 3、依赖倒置原则和控制反转、依赖注入的联系
  • 小结

1、依赖反转原则的定义和解读

SOILD原则中最后一个原则依赖反转原则(Dependency Inversion Principle,DIP)是指一种特定的解耦(传统的依赖关系创建在高层次上,而具体的策略设置则应用在低层次的模块上)形式,使得高层次的模块不依赖于低层次的模块的实现细节,依赖关系被颠倒(反转),从而使得低层次模块依赖于高层次模块的需求抽象。可以理解为依赖反转原则是指高层模块不应该依赖于底层模块,二者都应该依赖于抽象。抽象不应该依赖于具体实现,而具体实现应该依赖于抽象。简单来说,就是要依赖于抽象,而不是具体实现

2、稳定的抽象层

我们每次修改抽象接口的时候,一定会去修改对应的具体实现。但反过来,当我们修改具体实现时,却很少需要修改相应的抽象接口。所以我们可以认为接口比实现更稳定。

的确,优秀的软件设计师和架构师会花费很大精力来设计接口,以减少未来对其进行改动。毕竟争取在不修改接口的情况下为软件增加新的功能是软件设计的基础常识。

也就是说,如果想要在软件架构设计上追求稳定,就必须多使用稳定的抽象类接口,少依赖多变的具体实现。

下面是抽象工厂模式解决源代码依赖的问题,如图1所示来描述一下该设计模式的结构。如你所见,Application类是通过Service接口来使用ConcreteImpl类的。然而,Application类还是必须要构造ConcreteImpl类实例。于是,为了避免在源代码层次上引入对ConcreteImpl类具体实现的依赖,我们现在让Application类去调用ServiceFactory接口的makeSvc方法。这个方法就是由ServiceFactoryImpl类来具体提供,它是ServiceFactory的一个衍生类。该方法的具体实现就是初始化一个ConcreteImpl的实例,并且将其以Service类型返回。
在这里插入图片描述

图1 利用工厂模式管理依赖关系

图1中间的那条曲线代表了软件架构中的抽象层与具体实现层的边界。在这里,所有跨越这条边界源代码级别的依赖关系都应该单向的,即具体实现层依赖抽象层。

这条曲线将整个系统划分为两部分组件:抽象接口与具体实现。抽象接口组件中包含了应用的所有高阶业务规则,而具体实现组件中则包括了所有这些业务规则所需要做的具体操作及其相关的细节信息。

请注意,这里的控制流跨越架构边界的方向与源代码依赖关系跨越该边界的方向正好是相反的,源代码依赖方向永远是控制流方向的反转 - 这就是DIP被称为依赖反转的原因。

3、依赖倒置原则和控制反转、依赖注入的联系

控制反转(Inversion of Control,IoC)是一种实现依赖倒置原则的具体方式。它是通过将对象的创建、组装和管理交给IoC容器来实现的。在传统的程序设计中,我们通常是手动创建对象并直接调用它们的方法,而在IoC中,对象的创建和调用都是由容器来控制的。容器会在运行时动态地创建对象并将它们注入到需要它们的地方。

依赖注入(DI)是一种实现依赖倒置原则的方法,它通过将依赖对象的创建和管理工作交给外部容器(例如 DI 容器)来实现。依赖注入可以通过构造函数注入、属性注入或方法注入的方式来实现。一般来说,依赖注入使得高层模块不需要知道低层模块的具体实现,而只需要定义依赖接口,将依赖对象的创建和管理交给外部容器。依赖注入可以使得系统更加灵活、可扩展和易于测试,使得代码更易于维护和升级。

小结

下面我们将依赖反转原则归结为以下几点具体的编码守则:

  • 应在代码中多使用抽象接口,尽量避免使用那些多变的具体实现类。对此,我们通常会选择用抽象工厂这个设计模式。
  • 不要在具体实现类上创建衍生类
  • 不要覆盖(override)包含的具体实现函数
  • 应避免在代码中写入与任何具体实现相关的名字,或者是其他容易变动的事物的名字

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

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

相关文章

Linux零拷贝

零拷贝(Zero-copy)是一种优化技术,用于减少数据在内核空间和用户空间之间的拷贝次数,提高数据传输的效率和性能。它通过最小化数据的复制操作,将数据直接从源位置传输到目标位置,而不需要额外的数据拷贝。 …

微信小程序 构建npm报错: 没有找到可以构建的 NPM 包,请确认需要参与构建的 npm 都在 `miniprogramRoot` 目录内,

构建npm时报错 几个解决方案: 1、没有初始化项目 可以看这篇博客:微信小程序构建npm(js和ts 2、ts版本下记得修改删除project.config.json中setting字段下的一些内容 需要加或修改 "packNpmManually": true, "packNpmRe…

短视频矩阵系统软件源码---技术部署创建

矩阵系统源码主要有三种框架:Spring、Struts和Hibernate。Spring框架是一个全栈式的Java应用程序开发框架,提供了IOC容器、AOP、事务管理等功能。Struts框架是一个MVC架构的Web应用程序框架,用于将数据模型、Web应用程序的用户界面和控制器逻…

实战助力未来|“饶派杯”XCTF车联网安全挑战赛圆满收官!

2023年5月31日,“饶派杯”XCTF车联网安全挑战赛于江西省上饶市圆满落幕。本次大赛由江西省委网信办、江西省工信厅、上饶市人民政府主办,旨在深入贯彻落实国家网络强国和交通强国战略部署,推动智能网联汽车技术与产业发展、加快该领域人才培养…

【Linux】基于环形队列的生产者消费者模型

文章目录 基于环形队列的生产消费模型生产者和消费者的关注点申请和释放资源的问题规则 RingQueue.hpp单生产者单消费者的生产者消费者模型:信号量保护环形队列的原理多生产者多消费者模型计算任务处理RingQueue.hppTask.hppRingQueue.cc 基于环形队列的生产消费模型 环形队列…

安装pytourch gpu并测试

输入nvidia-smi命令查看cuda版本号, 系统的CUDA版本决定了系统最高可以支持什么版本的cudatoolkit,它是向下兼容的, 可以装低版本但是不能装高版本。 更新下conda,用管理员打开cmd conda update -n base -c defaults conda 安装CUDATookit 使用以下命令…

8 指数族分布【手写+Xmind笔记】

文章目录 8 指数族分布【手写Xmind笔记】8.1 Xmind笔记8.2 手写证明 8 指数族分布【手写Xmind笔记】 8.1 Xmind笔记 8.2 手写证明

第十二篇、基于Arduino uno,获取多个按键的输入信号(滤波消抖)——结果导向

0、结果 说明:先来看看串口调试助手显示的结果,当按下按键的时候,按一次会打印一次按键被按下,并且打印是哪个按键被按下。如果是你想要的,可以接着往下看。 1、外观 说明:虽然每个型号的按键形态各异&a…

Linux---用户的权限

专栏:Linux 个人主页:HaiFan. 本章为大家带来用户的权限的讲解 用户的权限 Linux权限的概念权限的三类对象权限的三种类型权限设置chmod/chown/chgrp更改权限chmodchownchgrp umask目录的权限粘滞位 Linux权限的概念 Linux下有两种用户:超级…

安科瑞应急照明的环境适用性

安科瑞 徐浩竣 江苏安科瑞电器制造有限公司 zx acrelxhj 摘要:论述消防应急照明和疏散指示系统在实际工程应用过程中系统产品选型、设置及维护环节普遍存在的问题,并提出相应的解决对策。 关键词:应急照明疏散指示产品选型环境适用性灯具…

机器学习笔记 - 使用稳定扩散模型创建图像

一、简述 文本到图像生成是机器学习 (ML) 模型从文本描述生成图像的任务。目标是生成与描述非常匹配的图像,捕捉文本的细节和细微差别。这项任务具有挑战性,因为它要求模型理解文本的语义和语法,并生成逼真的图像。文本到图像生成在 AI 摄影、概念艺术、建筑建筑、时尚、视…

用JMeter自动化测试实现高效稳定的接口测试方案!

目录 前言: 1. 接口与接口测试 1.1 接口概述 1.2 接口测试 2. 基于JMeter的接口测试 2.1 JMeter概述 2.2 用JMeter实现接口测试 3. 基于JMeter的接口自动化测试 3.1 接口自动化测试基础 3.2 使用JMeter进行接口自动化测试 总结 前言: 接口是…

(字符串) 541. 反转字符串 II——【Leetcode每日一题】

❓541. 反转字符串 II 难度:简单 给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。 如果剩余字符少于 k 个,则将剩余字符全部反转。如果剩余字符小于 2k 但大…

【dns awsl】RedHat8配置DNS服务器

文章目录 一、安装 配置DNS验证 一、安装 配置DNS 安装 sudo dnf install bind bind-utils配置named.conf 指定正向解析和反向解析的所需文件 vim /etc/named.conf在文件中找到options部分,并进行如下修改:options {listen-on port 53 { any; };allow…

day02——特征工程之特征提取

特征工程之特征提取 一、什么是特征工程二、特征提取1,字典特征提取2,文本特征提取(1)英文文本特征提取(2)中文文本特征提取(3)Tf-idf 文本特征提取 一、什么是特征工程 特征工程是…

CRM和SCRM有什么区别?

首先讲下CRM是什么?光是概念就有7个之多: 提出者概念GartnerGroupCRM是一种商业策略,它按照客户的分类情况有效地组织企业资源,培养以客户为中心的经营行为以及实施以客户为中心的业务流程,并以此为手段来提高企业的赢…

低代码平台安全性探究:解析低代码平台的安全性及应对措施

近年来,低代码平台由于能够以最少的代码快速开发应用程序而变得越来越流行。然而,随着数据泄露和网络威胁的增加,企业有理由质疑低码平台是否安全。在本文中,我们将探讨低代码平台安全吗? 一、低码平台如何工作。 在我…

集成websocket实现实时通信(ruoyi 使用笔记)

集成websocket实现实时通信(ruoyi 使用笔记 1.简单介绍WebSocket2.详细代码2.1WebSocketConfig2.2 SemaphoreUtils2.3 WebSocketServer2.4 WebSocketUsers2.5 html2.6 vue版本前端代码2.7 controller 1.简单介绍WebSocket Websocket 是一种基于 TCP 协议的全双工通信协议&#…

加油站“变身”快充站,探讨充电新模式

摘要:新能源汽车规模化发展的同时,充电不便利的痛点愈发明显。在未来的新能源汽车行业发展当中,充电的矛盾要远远大于造车的矛盾,解决好充电的问题成为电动汽车行业发展的一个突出问题。解决充电补能问题,重要的方式之…

自动化测试还是手动测试?深度探讨Web自动化测试的利与弊,精准性和可靠性抉择应如何。

目录 前言: 1. 自动化测试的价值 2. 自动化测试的瓶颈 总结 前言: 随着互联网的飞速发展,Web应用越来越成为我们日常工作和生活中必不可少的一部分。这也就意味着,Web应用的质量和稳定性变得至关重要。而Web自动化测试作为保…