软件设计模式原则(六)依赖倒置原则

news2024/11/28 2:46:01

一.定义

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

即:层次的模块不应该依赖于低层次的模块,它们都应该依赖于抽象;抽象不应该依赖于细节,细节应该依赖于抽象

目的:依赖倒置原则的目的是通过要面向接口的编程来降低类间的耦合性~

二.原理

        在设计软件时,应该将高层模块与低层模块之间的依赖关系进行颠倒。具体来说,高层模块不应该依赖于低层模块的细节实现,而应该依赖于抽象接口。这样的设计使得系统更加灵活和易于扩展,减少了模块间的耦合,使得代码更加稳定和易于测试。

        总结起来,依赖倒置原则是面向对象设计中的重要原则,通过将高层模块依赖于抽象接口,而不是低层模块的细节实现,能够实现松耦合的组件和更易于测试的代码。

三.引例

例1:在一个电商系统中,可能需要支持多种支付方式(如支付宝、微信、银行卡等)。通过定义一个抽象的支付接口,高层模块可以依赖于这个接口,而不是具体的支付实现。这样,当需要添加新的支付方式时,只需实现一个新的支付类,而无需修改高层模块的代码~

例2:在一个通知系统中,可能需要通过不同的方式(如邮件、短信、推送等)发送消息。通过定义一个抽象的消息发送接口,高层模块可以依赖于这个接口,而不是具体的消息发送实现。这样,当需要添加新的消息发送方式时,只需实现一个新的消息发送类,而无需修改高层模块的代码。

例3:数据读取:在一个系统中,可能需要从不同的数据源(如文件、数据库、网络等)读取数据。通过定义一个抽象的数据读取接口,高层模块可以依赖于这个接口,而不是具体的数据读取实现。这样,当需要添加新的数据读取方式时,只需实现一个新的数据读取类,而无需修改高层模块的代码。

例4:还是足球运动员的例子,在国家队招收球员时,可以从各国联赛(英法德西意)招募人员。通过建立一个专门的部门来负责,则总部可以从这里直接招收人,而不需要辗转各地发球星~这样,当有新的联赛崛起时(比甲、荷甲),只需要向专门的部门提供信息,而无需直接对接总部~

例5:假设我们有一个订单处理系统,其中包含订单类Order和邮件通知类EmailNotification,邮件通知类负责向客户发送订单确认邮件。传统的设计方式是在订单类中直接创建邮件通知类的实例来发送邮件通知,但这样的设计违背了依赖倒置原则。

下面是传统的设计方式:

class Order:
    def __init__(self, order_id, customer_name):
        self.order_id = order_id
        self.customer_name = customer_name
        self.email_notification = EmailNotification()

    def process(self):
        # 处理订单逻辑
        # 发送订单确认邮件
        self.email_notification.send_notification(self.customer_name)

在这个传统的设计中,订单类直接依赖于具体的邮件通知类EmailNotification,这样的设计使得订单类与邮件通知类紧密耦合,增加了代码的依赖性和可测试性。

而符合依赖倒置原则的设计方式是通过依赖注入来解耦:

class Order:
    def __init__(self, order_id, customer_name, notification_service):
        self.order_id = order_id
        self.customer_name = customer_name
        self.notification_service = notification_service

    def process(self):
        # 处理订单逻辑
        # 发送订单确认邮件
        self.notification_service.send_notification(self.customer_name)

在这个设计中,订单类通过构造函数接收一个抽象的通知服务notification_service,而不是直接创建具体的邮件通知类实例。这样的设计使得订单类与具体的邮件通知类解耦,提高了代码的灵活性和可测试性。

代码解析: 通过上述示例代码,我们可以看到传统的设计方式在订单类中直接创建了具体的邮件通知类实例,使得订单类与邮件通知类紧密耦合。而符合依赖倒置原则的设计方式通过依赖注入来解耦,使得订单类依赖于抽象的通知服务,而不依赖于具体的邮件通知类。这样的设计使得代码更加灵活、易于扩展和维护。

 

        

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

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

相关文章

线程池,及7大参数,4大拒绝策略详解

线程池,及7大参数,4大拒绝策略详解 1. 前言 1.1 什么是线程池? 线程池是一种利用池化技术思想来实现的线程管理技术,主要是为了复用线程、便利地管理线程和任务、并将线程的创建和任务的执行解耦开来。我们可以创建线程池来复用…

BearPi Std 板从入门到放弃 - 后天篇(2)(I2C1读写EEPROM)

简介 基于 BearPi Std 板从入门到放弃 - 后天篇(1)(I2C1 读取 光照强度), 使用同一个I2C接口访问EEPROM, 同时读取光照亮度 主芯片: STM32L431RCT6 LED : PC13 \ 推挽输出即可 \ 高电平点亮 串口: Usart1 I2C : I2C1 光照强度传感器&#xf…

谈一谈C++的类对象的存储方式

在C的类中,有成员变量和成员函数。当类经过实例化后,便有了类对象,C示例对象中的成员变量和成员函数是分开存储的。 成员变量 : 普通成员变量 : 在 对象 指针指向的内存中存储 , 存储方式与 C 语言中的 struct 结构体 存储变量的 内存结布局 …

IDEA插件配置--maven篇

仓库地址 IDEA中maven插件仓库默认地址:C:\Users\Administrator.m2\repository 在D盘新建一个文件夹用做本地仓库地址,例如 D:\Program Files\maven\repository,将原先C盘路径下的repository拷贝到D盘 修改settings.xml配置文件 镜像地…

springboot077基于SpringBoot的汽车票网上预订系统

springboot077基于SpringBoot的汽车票网上预订系统 成品项目已经更新!同学们可以打开链接查看!需要定做的及时联系我!专业团队定做!全程包售后! 2000套项目视频链接:https://pan.baidu.com/s/1N4L3zMQ9n…

项目经理是干出来的,不是教出来的

大家好,我是老原。 有不少新手项目经理,在通过了PMP认证考试,拿到PMP证书后,对之前无序的项目管理状态感觉有了一丝通透的感觉,对接受新项目更是信心满满。 然后就有不少没有项目管理经验,且刚刚考取PMP证…

FIR IP 学习记录

工具: matlab filterdesigner 工具箱 vivado FIR IP核 实现: 1.matlab设计与测试 先用matlab设计目标滤波器,得到滤波器的抽头系数。 如图,根据需求选择 低通/高通/带通/带阻。 由于vivado用的是FIR IP核,所以设…

更换cmd下默认选择Python解释器

问题 我的电脑里有多个Python解释器,一个是自己下载的python37,版本是3.7.0,一个是anaconda的base环境,版本是3.7.4,还有虚拟环境里的python解释器。 最近发现,在cmd下输入python,使用的是anac…

卡通渲染总结《一》

本文是在看完之前的综述论文《Cartoon Style Rendering》的总结,论文时间是2008年有点早,但有一定启发意义。 前言 首先卡通渲染是非真实化渲染(NPR)的一个部分.而NPR旨在模拟出手工插图的效果例如油画、墨水画、漫画风格作品。 …

【C++】const关键字的详解!!

💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤 📃个人主页 :阿然成长日记 …

在机器学习或者深度学习中是否可以直接分为训练集和测试集而不需要验证集?我的答案如下:

文章目录 一、训练集是什么?二、验证集是什么?三、测试集是什么?四、是否可以直接分为训练集和测试集而不需要验证集?总结 在机器学习和深度学习项目中,通常会将数据集划分为三个部分:训练集,验…

个人作品集

个人作品集 封面设计 排版设计 3D建模 Pr剪辑 个人剪辑作品 场景搭建

【ArcGIS Pro微课1000例】0049:根据坐标快速定位(创建点位)的常见方法

文章目录 一、转到XY1. 闪烁位置2. 平移3. 标记位置二、定位1. 坐标定位2. 添加到图形3. 添加至要素类三、添加XY坐标四、创建点要素一、转到XY 举例:经纬度坐标:113.2583286东, 23.1492340北 。 1. 闪烁位置 输入坐标,点击闪烁位置工具,即可在对应的位置出现一个绿色闪烁…

【“C++ 精妙之道:解锁模板奇谭与STL精粹之门“】

【本节目标】 1. 泛型编程 2. 函数模板 3. 类模板 4. 什么是STL 5. STL的版本 6. STL的六大组件 7. STL的重要性 8. 如何学习STL 9.STL的缺陷 1. 泛型编程 如何实现一个通用的交换函数呢? void Swap(int& left, int& right) {int temp left;lef…

Hadoop学习笔记(HDP)-Part.14 安装YARN+MR

目录 Part.01 关于HDP Part.02 核心组件原理 Part.03 资源规划 Part.04 基础环境配置 Part.05 Yum源配置 Part.06 安装OracleJDK Part.07 安装MySQL Part.08 部署Ambari集群 Part.09 安装OpenLDAP Part.10 创建集群 Part.11 安装Kerberos Part.12 安装HDFS Part.13 安装Ranger …

PRCD-1229 : An attempt to access configuration of database

今天维护oda一体机时,发现无法在grid用户下面关闭数据库实例,如下 ASM1:/home/gridoda0>srvctl stop database -d orcl -o immeidate PRCD-1229 : An attempt to access configuration of database orcl was rejected because its version 11.2.0.4.…

Lombok的踩坑系列之@Builder

背景: Lombok 这个插件大家日常工作中几乎是必备的,几个简单的注解就可以帮助我们减少一大坨get/set方法等;其中Builder注解使用的也很广泛,使用了建造者模式帮助我们构建出个性化的对象,本次踩坑点就在这个地方。 先…

智能优化算法应用:基于混沌博弈算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用:基于混沌博弈算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于混沌博弈算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.混沌博弈算法4.实验参数设定5.算法结果6.参考…

Learning Memory-guided Normality for Anomaly Detection 论文阅读

Learning Memory-guided Normality for Anomaly Detection 摘要1.介绍2.相关工作3.方法3.1网络架构3.1.1 Encoder and decoder3.1.2 Memory 3.2. Training loss3.3. Abnormality score 4.实验5.总结总结&代码复现: 文章信息: 发表于:cvpr…

我最喜欢的白版应用,AI加持的新功能开源!强烈推荐

Excalidraw 把他们的文本到图表的功能开源了 Excalidraw是一个虚拟白板应用,专门用于绘制类似手绘的图表。它提供了一个无限的、基于画布的白板,具有手绘风格,支持多种功能。 之前我分享的:72张PNG,图解机器学习 里面…