【Python】新手入门学习:详细介绍依赖倒置原则(DIP)及其作用、代码示例

【Python】新手入门学习:详细介绍依赖倒置原则(DIP)及其作用、代码示例
在这里插入图片描述

🌈 个人主页:高斯小哥
🔥 高质量专栏:Matplotlib之旅:零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程👈 希望得到您的订阅和支持~
💡 创作高质量博文(平均质量分92+),分享更多关于深度学习、PyTorch、Python领域的优质内容!(希望得到您的关注~)

博客链接简要说明
【Python】新手入门学习:详细介绍单一职责原则(SRP)及其作用、代码示例一个类应该只有一个引起变化的原因,确保类的职责单一。
【Python】新手入门学习:详细介绍开放封闭原则(OCP)及其作用、代码示例软件实体应对扩展开放,对修改封闭,提高系统的可维护性和可扩展性。
【Python】新手入门学习:详细介绍里氏替换原则(LSP)及其作用、代码示例子类必须能够替换其父类,且替换后,程序的行为没有变化。
【Python】新手入门学习:详细介绍依赖倒置原则(DIP)及其作用、代码示例高层模块不应该依赖于低层模块,二者都应该依赖于抽象。
【Python】新手入门学习:详细介绍接口分隔原则(ISP)及其作用、代码示例使用多个专门的接口,而不使用单一的总接口,降低类之间的耦合度。
【Python】新手入门学习:详细介绍组合/聚合复用原则(CARP)及其作用、代码示例尽量使用合成/聚合的方式达到复用,减少继承的使用。
【Python】新手入门学习:详细介绍迪米特原则(LoD)及其作用、代码示例一个对象应当对其他对象保持最少的了解,降低类之间的耦合度。

🌵文章目录🌵

  • 🎯一、什么是依赖倒置原则(DIP)?
  • 🔧二、DIP原则的作用
  • 📚三、如何实现DIP原则
  • 🔍四、DIP原则在实际项目中的应用
  • 💡五、违反DIP原则的后果
  • 🎉六、总结

🎯一、什么是依赖倒置原则(DIP)?

  依赖倒置原则(Dependency Inversion Principle,简称DIP)是面向对象设计原则中的一条重要原则。其核心思想是:要依赖于抽象,不要依赖于具体实现。换言之,高层模块不应该依赖于低层模块,它们都应该依赖于抽象;抽象不应该依赖于细节,细节应该依赖于抽象

  DIP原则鼓励我们在编写代码时,将抽象层与具体实现层进行分离,通过接口或抽象类来定义抽象层,而将具体的实现细节放在具体实现层中。这样,当具体实现发生变化时,只要接口或抽象类保持不变,高层模块就不会受到影响,提高了代码的可维护性和可扩展性。

🔧二、DIP原则的作用

DIP原则在软件设计中发挥着至关重要的作用,主要体现在以下几个方面:

  1. 降低耦合度:通过抽象层与具体实现层的分离,降低了模块之间的耦合度。当具体实现发生变化时,只需要修改具体实现层,而不需要修改高层模块,降低了代码的维护成本。

  2. 提高代码的可扩展性:由于高层模块依赖于抽象层,因此可以通过添加新的具体实现来扩展系统的功能,而无需修改现有代码。

  3. 促进代码复用:通过定义清晰的接口或抽象类,不同的模块可以共享相同的抽象层,从而实现代码的复用。

  4. 增强系统的灵活性:由于高层模块不直接依赖于具体实现,因此可以轻松地替换或升级具体实现,而不会影响到整个系统的运行。

📚三、如何实现DIP原则

要实现DIP原则,我们可以采取以下几个关键步骤:

  1. 定义抽象层:通过接口或抽象类来定义抽象层,明确高层模块所需的功能和行为。

  2. 编写具体实现:实现具体的类,这些类将继承自抽象类或实现接口,提供具体的功能实现。

  3. 高层模块依赖于抽象:在高层模块中,只引用抽象层,而不直接引用具体实现类。这样,高层模块就可以通过抽象层来调用具体实现的功能。

下面是一个简单的Python代码示例,展示了如何实现DIP原则:

from abc import ABC, abstractmethod# 定义抽象层
class Shape(ABC):@abstractmethoddef area(self):pass# 具体实现
class Circle(Shape):def __init__(self, radius):self.radius = radiusdef area(self):return 3.14 * self.radius ** 2class Rectangle(Shape):def __init__(self, width, height):self.width = widthself.height = heightdef area(self):return self.width * self.height# 高层模块依赖于抽象
def calculate_total_area(shapes):total_area = 0for shape in shapes:total_area += shape.area()return total_area# 使用示例
shapes = [Circle(5), Rectangle(10, 20)]
total_area = calculate_total_area(shapes)
print(f"Total area: {total_area}")

在这个例子中:

  1. 抽象层定义Shape 类是一个抽象基类,它定义了一个抽象的 area 方法。

  2. 具体实现CircleRectangle 类是 Shape 的具体实现,它们分别实现了 area 方法,用来计算各自的面积。

  3. 高层模块依赖于抽象calculate_total_area 函数是一个高层模块,它依赖于 Shape 抽象,而不是依赖于具体的 CircleRectangle 类。它接收一个 Shape 对象的列表,并调用每个对象的 area 方法来计算总面积。

  4. 细节依赖于抽象CircleRectangle 类作为细节,它们实现了 Shape 抽象中定义的 area 方法。

  这样的设计使得 calculate_total_area 函数可以独立于具体的形状类,只要它们实现了 Shape 抽象中定义的接口。如果将来需要添加新的形状类,只要这个新类也实现了 Shape 接口,calculate_total_area 函数就可以无缝地与之集成。因此,这个代码示例遵循了依赖倒置原则,使得系统更加灵活、可维护和可扩展。

🔍四、DIP原则在实际项目中的应用

  在实际项目中,DIP原则的应用广泛而重要。它常常与工厂模式、策略模式等设计模式一起使用,以实现代码的灵活性和可扩展性。

  例如,在一个复杂的业务系统中,我们可能需要处理多种不同类型的支付方式(如支付宝、微信支付、银行卡支付等)。每种支付方式都有自己的支付逻辑和接口。这时,我们可以定义一个抽象的 Payment 接口,然后为每种支付方式实现一个具体的类。业务逻辑层则依赖于 Payment 接口,而不是具体的支付实现类。这样,当需要添加新的支付方式时,我们只需要实现新的支付类,并将其注册到系统中,而无需修改现有的业务逻辑代码。

💡五、违反DIP原则的后果

如果违反了DIP原则,会导致一系列不良后果:

  1. 代码紧耦合:当高层模块直接依赖于具体实现时,不同模块之间会形成紧密的耦合关系。一旦具体实现发生变化,高层模块也必须进行相应的修改,这增加了代码的维护难度和成本。

  2. 难以扩展新功能:如果高层模块直接依赖于具体实现,那么添加新的功能或修改现有功能将变得困难。因为每次变动都需要修改高层模块的代码,这限制了系统的可扩展性。

  3. 测试困难:当高层模块与具体实现紧密耦合时,测试也会变得困难。因为测试人员需要模拟具体的实现细节,以验证高层模块的正确性。这增加了测试的复杂性和工作量。

  4. 降低了代码复用性:如果每个高层模块都直接依赖于具体的实现,那么不同的模块之间很难共享相同的抽象层。这导致了代码的重复和冗余,降低了代码的复用性。

  因此,遵循DIP原则对于保持代码的健壮性、灵活性和可维护性至关重要。它有助于我们构建出易于扩展、易于测试、易于维护的软件系统。

🎉六、总结

  依赖倒置原则(DIP)是面向对象设计中的重要原则之一。它强调高层模块应该依赖于抽象而不是具体实现,使得代码更加灵活、可扩展和易于维护。通过定义清晰的抽象层和具体实现层,我们可以降低模块之间的耦合度,提高代码的可复用性和可测试性。

  在实际项目中,我们应该积极应用DIP原则,通过接口或抽象类来定义抽象层,将具体实现细节放在具体实现层中。这样,当具体实现发生变化时,我们只需要修改具体实现层,而无需修改高层模块,从而降低了代码的维护成本。

  同时,我们也应该避免违反DIP原则,以免导致代码紧耦合、难以扩展和测试困难等问题。通过遵循DIP原则,我们可以构建出更加健壮、灵活和可维护的软件系统。

  希望本文的介绍能够帮助你更好地理解依赖倒置原则,并在实际开发中灵活运用。通过不断实践和积累经验,我们可以逐渐提高软件设计的能力,创造出更加优秀和可靠的软件系统。

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

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

相关文章

如何将.txtpb在IDE中彩色高亮显示

1. 问题描述 文件内容片段如下,它采用了一种键值对的格式,其中还包括了注释。我们可以采用一种近似的语言色彩识别方案处理它,比如YAML或者Python的语法高亮规则,因为这两种语言在处理键值对和注释的表示上与内容片段相似。当然也…

【QT+QGIS跨平台编译】之七十三:【QGIS_Analysis跨平台编译】—【错误处理:字符串错误】

文章目录 一、字符串错误二、处理方法三、涉及到的文件一、字符串错误 常量中有换行符错误:(也有const char * 到 LPCWSTR 转换的错误) 二、处理方法 需要把对应的文档用记事本打开,另存为 “带有BOM的UTF-8” 三、涉及到的文件 涉及到的文件有: src\analysis\processin…

openssl3.2 - exp - 选择最好的内建椭圆曲线

文章目录 openssl3.2 - exp - 选择最好的内建椭圆曲线概述笔记将 openssl ecparam -list_curves 实现迁移到自己的demo工程备注END openssl3.2 - exp - 选择最好的内建椭圆曲线 概述 在openssl中使用椭圆曲线, 只允许选择椭圆曲线的名字, 无法给定椭圆曲线的位数. 估计每种椭…

深度学习armv8/armv9 cache的原理

文章目录 前言1、为什么要用cache?2、背景:架构的变化?2、cache的层级关系 ––big.LITTLE架构(A53为例)3、cache的层级关系 –-- DynamIQ架构(A76为例)4、DSU / L3 cache5、L1/L2/L3 cache都是多大呢6、cache相关的术语介绍7、cache的分配策略(alocat…

C++函数 加括号与不加括号

很多时候,我们会看到一些在创建对象时有的加括号有的不加括号 那么,这是什么情况呢? 总结:函数需要加上括号,加上括号会对函数初始化,不加括号可能导致未知错误 我们来验证一下。 1.基本数据类型不带括…

利用Python进行网络爬虫:Beautiful Soup和Requests的应用【第131篇—Beautiful Soup】

利用Python进行网络爬虫:Beautiful Soup和Requests的应用 在网络数据变得日益丰富和重要的今天,网络爬虫成为了获取和分析数据的重要工具之一。Python作为一种强大而灵活的编程语言,在网络爬虫领域也拥有广泛的应用。本文将介绍如何使用Pyth…

Elasticseach基础认识

ES的起源? Elasticsearch 是由 Elastic 公司创建 简称(ES) Elasticsearch 是一个分布式、免费和开放的搜索和分析引擎,适用于所有类型的数据,包括文本、数字、地理空间、结构化和非结构化数据。 Elasticsearch 基于 …

Oracle 主从切换脚本

一、 切换前预检查 1. dg_precheck_main_v1.4.sh #!/bin/bash#********************************************************************************** # Author: Hehuyi_In # Date: 2022年06月16日 # FileName: dg_precheck_main_v1.4.sh # # For sys user, execute the sc…

LLM之RAG实战(二十九)| 探索RAG PDF解析

对于RAG来说,从文档中提取信息是一种不可避免的场景,确保从源文件中提取出有效的内容对于提高最终输出的质量至关重要。 文件解析过程在RAG中的位置如图1所示: 在实际工作中,非结构化数据比结构化数据丰富得多。如果这些海量数据无…

如何使用vue定义组件之——子组件调用父组件数据

1.定义父子模板template <div class"container"><my-father></my-father><my-father></my-father><my-father></my-father><!-- 此处无法调用子组件&#xff0c;子组件必须依赖于父组件进行展示 --><!-- <my-…

数学实验_Matlab使用2_简单绘图

简单使用 x -pi * 2 : .1 : pi*2;y sin(x);plot(x, y); % 绘制普通图像plot(x, y, k-.*); % 绘制2维图像&#xff0c;线为实线&#xff0c;*为每个点&#xff08;Matlab的画图比较原始&#xff0c;就是简单的秒点画图&#xff09;grid on; % 打开网状格式% grid off; % 关闭…

SORA和大语言模型的区别

OpenAI的文生视频模型SORA与大语言模型&#xff08;LLM&#xff09;的主要区别在于它们的应用领域和处理的数据类型&#xff0c;数据处理能力、技术架构、多模态能力和创新点。SORA作为一款专注于视频生成的模型&#xff0c;展现了在处理视觉数据方面的独特优势和创新能力。 1…

R语言读取大型NetCDF文件

失踪人口回归&#xff0c;本篇来介绍下R语言读取大型NetCDF文件的一些实践。 1 NetCDF数据简介 先给一段Wiki上关于NetCDF的定义。 NetCDF (Network Common Data Form) is a set of software libraries and self-describing, machine-independent data formats that support…

STM32串口通信—串口的接收和发送详解

目录 前言&#xff1a; STM32串口通信基础知识&#xff1a; 1&#xff0c;STM32里的串口通信 2&#xff0c;串口的发送和接收 串口发送&#xff1a; 串口接收&#xff1a; 串口在STM32中的配置&#xff1a; 1. RCC开启USART、串口TX/RX所对应的GPIO口 2. 初始化GPIO口 …

YOLOv8改进 | 图像去雾 | 特征融合注意网络FFA-Net增强YOLOv8对于模糊图片检测能力(北大和北航联合提出)

一、本文介绍 本文给大家带来的改进机制是由北大和北航联合提出的FFA-net: Feature Fusion Attention Network for Single Image Dehazing图像增强去雾网络,该网络的主要思想是利用特征融合注意力网络(Feature Fusion Attention Network)直接恢复无雾图像,FFA-Net通过特征…

MyBatis-Plus学习记录

目录 MyBatis-Plus快速入门 简介 快速入门 MyBatis-Plus核心功能 基于Mapper接口 CRUD 对比mybatis和mybatis-plus&#xff1a; CRUD方法介绍&#xff1a; 基于Service接口 CRUD 对比Mapper接口CRUD区别&#xff1a; 为什么要加强service层&#xff1a; 使用方式 CR…

开发指南009-从list导出excel文件

从数据库返回一般是对象的列表&#xff0c;平台底层提供了从list转为excel文件的方法。平台的设计思想就是为一些典型的场景设计对应的解决方法&#xff0c;通过模式化的方法来简化编程和提高维护性&#xff08;通过标准化来减少学习成本和维护成本&#xff0c;张三做的东西和李…

游戏数据处理

游戏行业关键数据指标 ~ 总激活码发放量、总激活量、总登录账号数 激活率、激活登录率 激活率 激活量 / 安装量 激活率 激活量 / 激活码发放量 激活且登录率 激活且登录量 / 激活码激活量 激活且登录率应用场景 激活且登录率是非常常用的转化率指标之一&#xff0c;广泛…

Ypay源支付6.9无授权聚合免签系统可运营源码

YPay是一款专为个人站长设计的聚合免签系统&#xff0c;YPay基于高性能的ThinkPHP 6.1.2 Layui PearAdmin架构&#xff0c;提供了实时监控和管理的功能&#xff0c;让您随时随地掌握系统运营情况。 说明 Ypay源支付6.9无授权聚合免签系统可运营源码 已搭建测试无加密版本…

HTML5:七天学会基础动画网页13

看完前面很多人可能还不是很明白0%-100%那到底是怎么回事&#xff0c;到底该怎么用&#xff0c;这里我们做一个普遍的练习——心跳动画 想让心❤跳起来&#xff0c;我们先分析一波&#xff0c;这个心怎么写&#xff0c;我们先写一个正方形&#xff0c;再令一个圆形前移: 再来一…