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

一.定义

        依赖倒置原则(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,而不是直接创建具体的邮件通知类实例。这样的设计使得订单类与具体的邮件通知类解耦,提高了代码的灵活性和可测试性。

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

 

        

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot整合validation数据校验

1. 首先引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency> 点标识进去可以发现是通过Hibernate Validator使用 Java Bean Validation 2. 属性上…

用AI在抖音直播做姓氏头像的全新玩法,详细分析制作教程

前段时间在圈子里给大家分享了用AI写艺术字做小红书账号案例玩法&#xff0c;同学们都比较热衷学习。纷纷动手实践。 事实上用AI艺术字变现玩法还有许多。 例如上周末在星球给圈友们分享的一个AI艺术字直播的抖音账号&#xff0c;直播内容形式很简单&#xff0c;就是展现用AI…

从一个简单的实际例子看并行处理

在不使用并行处理之前 假如我有一个很大的tif图片 我想算一下这张图片中有多少的像素点是黑色的,我可能会这么做: def cnt_black(filename):img = tf.imread(filename)width, height, channels = img.shapecnt = 0for i in range(width):for j in range(height):r, g, b = …

12、SQL注入——SQL报错注入

文章目录 一、报错注入概述1.1 报错注入1.2 报错注入的前提条件1.3 相关报错函数 二、报错注入payload2.1 利用extractvalue()函数进行报错注入2.2 利用updataxml()函数进行报错注入2.3 利用floor()函数进行报错注入 一、报错注入概述 1.1 报错注入 通过构造特定的SQL语句&am…

coding创建远程分支。并拉取远程新分支+推送代码

进入coding ----项目----代码仓库---点击 下拉之后查看全部----创建分支 创建分支之后执行下面命令 git branch -a // 查看所有分支 这个时候发现自己创建的分支没有显示这是因为自己在远程创建了分支但是本地还没有分支 执行 git fetch命令 用于从远程仓库获取最新的提交…

【软件测试】技术精选:Jmeter常见的几种报错

1、Java.net.UnknownHostException 这个错的含义是 没有连接到服务器地址&#xff0c;因此很可能是 内部网络中断导致。 2、502 Bad gateway 这个和本地的线程数无关 可能原因是网络抖动不稳定导致 3、java.net.SocketException: Socket closed 强制停止线程&#xff0c;连接…

CSRF之pikachu靶场DW

1&#xff0c;登录皮卡丘靶场&#xff0c;get请求&#xff1b; 2&#xff0c;抓包并修改标记后的个人信息 最后放通一下&#xff0c;发现账号信息被修改 2&#xff0c;post请求 1提交post数据并使用bp抓包 2.利用工具改包&#xff0c;并生成url 3&#xff0c;点击提交后&#…

单调栈与单调队列算法总结

单调栈 知识概览 单调栈最常见的应用是找到每一个数离它最近的且比它小的数。单调栈考虑的方式和双指针类似&#xff0c;都是先想一下暴力做法是什么&#xff0c;然后再挖掘一些性质如单调性&#xff0c;最终可以把目光集中在比较少的状态中&#xff0c;从而达到降低时间复杂…

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

为什么要使用线程池 线程的生命周期&#xff1a;运行、就绪、运行、阻塞、死亡 下面是一个简单的创建多线程的方法。注意&#xff1a;工作中不可取。 创建线程的时候&#xff0c;我们避不开线程的生命周期。上面的方法虽然可以创建多线程&#xff0c;但是创建完成后&#xff0c…

智能优化算法应用:基于寄生捕食算法无线传感器网络(WSN)覆盖优化 - 附代码

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

深入探讨Guava的缓存机制

第1章&#xff1a;引言 大家好&#xff0c;我是小黑&#xff0c;今天咱们聊聊Google Guava的缓存机制。缓存在现代编程中的作用非常大&#xff0c;它能提高应用性能&#xff0c;减少数据库压力&#xff0c;简直就是性能优化的利器。而Guava提供的缓存功能&#xff0c;不仅强大…

vue el-select多选封装及使用

使用了Element UI库中的el-select和el-option组件来构建多选下拉框。同时&#xff0c;也包含了一个el-input组件用于过滤搜索选择项&#xff0c;以及el-checkbox-group和el-checkbox组件用于显示多选项。 创建组件index.vue (src/common-ui/selectMultiple/index.vue) <tem…

【优选算法系列】【专题一双指针】第四节.15. 三数之和和18. 四数之和

文章目录 前言一、三数之和 1.1 题目描述 1.2 题目解析 1.2.1 算法原理 1.2.2 代码编写 1.2.3 题目总结二、四数之和 2.1 题目描述 2.2 题目解析 2.2.1 算法原理 2.2.2 代码编写 …

什么是动态住宅IP?它有什么用途?

随着网络的迅速发展&#xff0c;许多人对代理IP已经有了比较深刻的认识&#xff0c;并且广泛地运用到了各自的业务中&#xff0c;尤其在跨境的相关业务中表现尤其卓越。对于代理IP的类别&#xff0c;也需要根据自己的业务类型具体选择最合适的&#xff0c;那么今天IPFoxy就给大…

【Vue】使用cmd命令创建vue项目

上一篇&#xff1a; node的安装与配置 https://blog.csdn.net/m0_67930426/article/details/134562278?spm1001.2014.3001.5502 目录 一.创建空文件夹专门存放vue项目 二. 查看node , npm 和vue脚手架的版本 三.安装vue脚手架 四.创建vue项目 五.运行项目 一.创建空文件…

File类—递归文件搜索执行脚本文件

文章目录 一、需求分析二、File类2.1 File对象的创建2.2 File判断和获取方法2.3 创建和删除方法2.4 遍历文件夹方法 三、Runtime类—常见api四、递归文件搜索执行脚本文件 一、需求分析 在本篇博客中&#xff0c;我们想通过递归文件的方式&#xff0c;在D:\\判断下搜索QQ.exe这…

Hadoop学习笔记(HDP)-Part.07 安装MySQL

目录 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 …

生成式 AI 应用落地小结:高估的模型能力,低估的工程实施

虽然 ChatGPT 已经诞生了一周年&#xff0c;但是大量的人依旧对于生成式 AI 没有足够的认识。在研发领域&#xff0c;Thoughtworks 一直在与不同的大型企业合作&#xff0c;保持开放性的探索。 在我负责的 Thoughtworks 开源社区&#xff0c;我们与外部的几家大型企业一起探索和…

YOLOv8创新魔改教程(三)如何添加注意力机制注意力机制的用法与思考

注意力机制的用法与思考 好多同学问我加了CA注意力机制&#xff0c;CBAM注意力机制&#xff0c;都没有涨点&#xff0c;然后就在不停地换不同的注意力机制&#xff0c;其实并不是这样的。今天和大家讨论一下注意力机制的用法与思考。 &#xff08;一&#xff09;添加位置 大…

Vmware17虚拟机安装windows10系统

不要去什么系统之家之类的下载镜像&#xff0c;会不好安装&#xff0c;镜像被魔改过了&#xff0c;适合真实物理机上的系统在PE里安装系统&#xff0c;建议下载原版系统ISO文件 安装vmware17pro 下载地址https://dwangshuo.jb51.net/202211/tools/VMwareplayer17_855676.rar 解…