大话设计模式-依赖倒转原则

依赖倒转原则

在大话设计模式这本书中,作者通过电话修电脑这个例子引入了面向对象设计的基本原则之一:依赖倒转原则

概念

依赖倒转原则是面向对象设计的基本原则之一,它用于减少类之间的耦合,提高系统的灵活性和可维护性。在书中,依赖倒转原则的原话解释是抽象不应该依赖细节,细节应该依赖于抽象。它的主要内容可以分为两个部分:

  1. 高层模块不应该依赖低层模块。两者都应该依赖其抽象。
  2. 抽象不应该依赖于细节。细节应该依赖于抽象。
    简单点说,就是我们在编程的时候要依赖于抽象(接口或抽象类),不要依赖于具体的类(对象)。

这一原则与我们前文中所讲解的里氏代换原则相辅相成,当我们满足里氏代换原则时,子类能够完全替换父类。而满足依赖倒转原则时,细节依赖于抽象(抽象类一般是父类)。因此当同时遵循这两个原则的时候,我们的代码就能够通过子类灵活的进行扩展。

例子

光讲上面的概念可能难以理解其中的含义,这里举一个具体的例子。

  • 假设我们正在开发一个新闻应用,这个应用有一个NewsService类,它负责从不同的新闻源获取新闻。一开始,我们只从网络获取新闻,所以我们可能会有以下的设计:
class NewsService {
    NetworkNewsFetcher fetcher;

    NewsService() {
        this.fetcher = new NetworkNewsFetcher();
    }

    List<News> getNews() {
        return fetcher.fetch();
    }
}

class NetworkNewsFetcher {
    List<News> fetch() {
        // fetch news from the network
    }
}

在这个设计中,NewsService直接依赖于NetworkNewsFetcher,这意味着如果我们想从其他来源(如本地文件)获取新闻,我们就需要修改NewsService的代码。
现在,让我们按照依赖倒转原则来重新设计这个系统:

interface NewsFetcher {
    List<News> fetch();
}

class NewsService {
    NewsFetcher fetcher;

    NewsService(NewsFetcher fetcher) {
        this.fetcher = fetcher;
    }

    List<News> getNews() {
        return fetcher.fetch();
    }
}

class NetworkNewsFetcher implements NewsFetcher {
    @Override
    public List<News> fetch() {
        // fetch news from the network
    }
}

class LocalNewsFetcher implements NewsFetcher {
    @Override
    public List<News> fetch() {
        // fetch news from a local file
    }
}

  • 在这个新的设计中,NewsService依赖于NewsFetcher接口,而不是具体的NetworkNewsFetcher类。这样,我们就可以在不修改NewsService的代码的情况下,通过添加新的NewsFetcher实现(如LocalNewsFetcher)来扩展系统的功能。这个例子是通过代码来解释依赖倒转原则,能够帮助有一定编程基础的同学能够更加清晰地体会到依赖倒转原则的优点。

优缺点

在大话设计模式中,有这样一句话:可以把PC电脑理解成是大的软件系统,任何部件如CPU、内存、硬盘、显卡等都可以理解为程序中封装的类或程序集,由于PC易插拔的方式,那么不管哪一个出问题,都可以在不影响别的部件的前提下进行修改或替换。

在这句话中 PC电脑依赖于CPU、内存、硬盘、显卡等硬件设备,而这些硬件损坏的时候,我们能够很方便的对其进行更换,这就依赖于PC易插拔的方式。我们可以思考一个这样的问题,PC易插拔的方式是怎么做到的?其实就是因为它遵循了依赖倒置原则,严格意义上来讲,PC电脑所依赖的并不是具体的某一块CPU、内存、硬盘、显卡等硬件设备,而是依赖能够插进主板插槽的硬件设备。而这个主板预留出的插槽其实就是我们前面所谓的“抽象”(接口或抽象类),只有主板依赖于插槽,这些硬件的生产厂商,再根据插槽的形状去做对应的硬件,才能够实现PC易插拔。否则, 如果PC依赖的具体的某一块CPU、内存、硬盘、显卡等硬件设备,那如果硬件设备坏了,就得整个PC都换掉,因为PC只“用得惯”这一块硬件。

因此,总结一下依赖倒转原则的优点:它使我们的代码更加灵活,更容易扩展和维护。
在这里插入图片描述

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

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

相关文章

明道云HAP合作伙伴计划全解析:开辟业务增长新路径

什么是明道云HAP合作伙伴计划&#xff1f; 明道云采纳的是增值伙伴商业模式。在这个模式下&#xff0c;合作伙伴通过平台型产品为终端客户提供定制应用、行业解决方案、赋能培训等增值活动&#xff0c;从而在大幅降低交付成本的同时获得多来源的收入&#xff0c;提高经营绩效水…

PLC中连接外部现场设备和CPU的桥梁——输入/输出(I/O)模块

输入&#xff08;Input&#xff09;模块和输出&#xff08;Output&#xff09;模块简称为I/O模块&#xff0c;数字量&#xff08;Digital&#xff0c;又称为开关量&#xff09;输入模块和数字量输出模块简称为DI模块和DQ模块&#xff0c;模拟量&#xff08;Analog&#xff09;输…

RK3568 android11 修改关机弹窗界面

需要修改关机弹窗界面&#xff0c;当前界面我已经按照客户需求去掉emergency 但是客户需要按其他区域可以实现返回&#xff0c;也就是点击黑色背景取消dialog 嗑代码发现黑色布局为&#xff1a; <node index"0" text"" resource-id"com.android.…

【Redis】string数据类型

文章目录 常用命令setsetnx & NXXXsetex & EXpsetex & PX msetget & mgetincr & decrincrby & decrbyincrbyfloatappendgetrangesetrangestrlen 内部编码 字符串类型是 Redis 最基础的数据类型。 在redis中所有的键都是 string 类型&#xff0c;其他的…

oracle操作系统OS认证和密码文件认证

1 说明 1.1 常见认证方式 Oracle登录认证方式主要涉及到如何验证用户身份以访问数据库。Oracle数据库提供了多种认证机制来确保数据的安全性和访问控制&#xff0c;每种方式都有其特定的使用场景和安全性考虑。以下是Oracle中常见的登录认证方式&#xff1a; 1、基于操作系统…

Vue-鼠标悬浮在缩略图图片上,弹出原图

使用Popover 弹出框实现 <template><div><el-popoverplacement"right"width"400"trigger"hover"><img src"https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x36…

三维天地低代码平台实现客户需求的快速交付与灵活定制

— 款合格的低代码平台应具备架构稳定、 产品质量高、 交付速度快、 运维简便的特点, 能快速实现业务需求到系统功能落地。 二十余年来, 北京三维天地科技股份有限公司一直专注于实验室信息化管理 领域, 旗下 SW- LIMS 已在化工、 环保、 食品、 科研等二十余个行业广泛应用,服…

PyTorch and Stable Diffusion on FreeBSD

Stable Diffusion在图像生成领域具有广泛的应用和显著的优势。它利用深度学习和扩散模型的原理&#xff0c;能够从随机噪声中生成高质量的图像。 官网&#xff1a;GitHub - verm/freebsd-stable-diffusion: Stable Diffusion on FreeBSD with CUDA support FreeBSD下难度主要…

docker安装并跑通QQ机器人实践(4)-bs-cqhttp搭建

go-cqhttp&#xff0c;基于 Mirai 以及 MiraiGo 的 OneBot Golang 原生实现&#xff0c;只需简单的配置, 就可以基于 go-cqhttp 使用框架开发&#xff0c;具有轻量, 原生, 高并发, 低占用, 跨平台等特点。 1 go-cqhttp 官网及可执行文件下载链接 go-cqhttp 官网&#xff1a;ht…

项目实践---贪吃蛇游戏的实现

上一章&#xff0c;我们已经分析了贪吃蛇的具体内容&#xff0c;包括它是如何实现的&#xff0c;怎样完成这个项目的&#xff0c;其中就提到了 贪吃蛇有三个代码&#xff1a;一个是测试代码&#xff0c;一个是头文件代码&#xff0c;还有一个是主函数代码。那么今天我们就来讲一…

【大数据】TiDB: A Raft-based HTAP Database

文章目录 数据库知识介绍数据库系统的ACID特性分布式系统和CAP理论关系型数据库与非关系型数据库关系型数据库非关系型数据库 OldSQL、NoSQL、NewSQLOldSQLNoSQLNewSQL OLTP、OLAP、HTAP 前言&#xff1a;为什么选择TiDB学习&#xff1f;pingCAP介绍TiDB介绍TiDB的影响力TiDB概…

什么是大语言模型以及如何构建自己的大型语言模型?

一、关于大语言模型 LLM 对于无数的应用程序非常有用&#xff0c;如果我们自己从头开始构建一个&#xff0c;那我们可以了解底层的ML技术&#xff0c;并可以根据特定需求定制LLM&#xff0c;但是对资源的需求巨大。大型语言模型是一种 ML 模型&#xff0c;可以执行各种自然语言…

《QT实用小工具·二十八》基于qt开发的各种曲线

1、概述 源码放在文章末尾 该项目实现了各种曲线的绘制&#xff0c;下面是项目的demo演示&#xff1a; 项目部分代码如下&#xff1a; #include "frmsmoothcurve.h" #include "ui_frmsmoothcurve.h" #include "smoothcurve.h" #include "…

【ThinkPHP框架教程·Part-01】ThinkPHP6.x框架安装教程

文章目录 一、框架介绍1、框架简介和版本选择2、主要新特性 二、安装步骤1、下载并运行Composer-Setup.exe2、安装TP前切换镜像3、安装稳定版4、测试运行 一、框架介绍 1、框架简介和版本选择 Thinkphp是一种基于php的开源web应用程序开发框架ThinkPHP框架&#xff0c;是免费开…

Axure设计原型图工具 Windows11安装步骤详解

文章目录 目录 文章目录 安装流程 小结 概要安装流程技术细节小结 概要 Axure 是一个流行的原型设计工具&#xff0c;它被用来创建交互式原型、线框图和用户界面设计。Axure 可以帮助用户在项目早期阶段快速制作出可交互的原型&#xff0c;以便进行用户测试、验证设计概念和与…

jetcache fastjson 泛型复杂对象JSON序列 ,反序列化

Jetcache fastjson 泛型复杂对象JSON序列 ,反序列化 默认的FastJson2 序列化存在问题增强FastJson 支持Encode 编码器Decode 解码器 默认的FastJson2 序列化存在问题 默认的序列化不能转换List 中的泛型数据类型, 从缓存拿取的list集合对象数据全部都转换成了JSONObject 增强F…

UE5 把蓝图内的变量和事件暴露给序列使用

在蓝图变量内勾选Expose to Cinematics 事件: 在角色内添加自定义事件 在序列内对着角色的号添加Event,选择Trigger 添加关键帧,然后在关键帧右键添加class,在class下绑定事件

fdisk使用的MBR分区

MBR和GPT分区 MBR分区 MBR分区一般在分区的时候 &#xff0c;MBR分区格式只能支持2TB以下的硬盘容量。 分区最多为4个主分区 或 3个主分区和1个扩展分区&#xff0c;而创建扩展分区后可以分无数个逻辑分区&#xff0c;当然跟磁盘容量有关&#xff0c; 逻辑分区在扩展分区上…

K210基础实验——独立按键中断

前言 学习K210开发板的独立按键和中断功能 一、涉及到的外设资源是K210开发板上的BOOT按键和RGB灯 二、BOOT按键按下&#xff0c;MCU上连接BOOT的IO口变为低电平&#xff0c;松开后为高电平 三、引脚对应关系 BOOT : IO16 RGB灯&#xff1a; R:IO6 G:IO7 B:IO8 四、在…

A-1:树状数组

A-1:树状数组 1.介绍Q1:树状数组解决什么问题&#xff1f;Q2:树状数组的使用1.前置知识&#xff1a;lowbit(x)2.单点修改3.求[1,n]的和4.区间查询5.hh Q3:树状数组是否优化了Q4:上图上例子解释上面说的东西(Important) 2.习题练习 1.介绍 树状数组是一个比较难以理解的高级数据…