依赖倒置原则
当然可以!这次我们来详细讲解 依赖倒置原则(DIP: Dependency Inversion Principle),它是 SOLID 五大设计原则中的压轴,也是最关键的“架构型原则”。
我将从:
- 什么是依赖倒置原则(定义)
- 为什么需要(价值)
- 优劣对比
- Python 例子(先错再对)
- Mermaid 图(清晰结构)
带你完整理解它。
🧠 一句话定义
高层模块不应该依赖低层模块,二者都应该依赖于抽象。抽象不应该依赖于细节,细节应该依赖于抽象。
简化版本:
程序要依赖接口,而不是依赖实现。
🎯 为什么需要依赖倒置原则?
你有没有遇到过:
- 改了一个类,连锁影响到很多地方?
- 想替换一个模块,但发现到处都“绑死”了原来的类?
这就是因为:
高层模块直接依赖低层细节 → 系统结构僵硬,耦合严重!
✅ 优点 vs ❌ 缺点
优点(为什么需要) | 缺点 |
---|---|
✅ 解耦上下层模块 | 初学者理解难 |
✅ 方便测试、Mock | 多了抽象接口 |
✅ 易扩展和替换 | 程序启动需明确注入依赖 |
✅ 结构更清晰 | 设计成本略升 |
🐍 Python 示例
❌ 错误示范:高层模块依赖底层类
class MySQLDatabase:def connect(self):print("Connected to MySQL")class UserService:def __init__(self):self.db = MySQLDatabase() # ❌ 直接依赖具体类def get_user(self):self.db.connect()print("Getting user from database")
问题:
UserService
绑死了MySQLDatabase
;- 不能轻松换成 MongoDB、Mock 测试版本。
✅ 正确示范:依赖倒置 + 依赖注入
from abc import ABC, abstractmethod# --------------------
# 抽象接口
# --------------------
class Database(ABC):@abstractmethoddef connect(self):pass# --------------------
# 具体实现类
# --------------------
class MySQLDatabase(Database):def connect(self):print("Connected to MySQL")class MongoDatabase(Database):def connect(self):print("Connected to MongoDB")# --------------------
# 高层模块(业务逻辑)
# --------------------
class UserService:def __init__(self, db: Database): # 依赖抽象,不依赖具体实现self.db = dbdef get_user(self):self.db.connect()print("Getting user from the database")# --------------------
# 主程序入口(运行时注入依赖)
# --------------------
if __name__ == "__main__":# 使用 MySQLmysql_db = MySQLDatabase()user_service_mysql = UserService(mysql_db)user_service_mysql.get_user()print()# 使用 MongoDB(只换对象,不改逻辑)mongo_db = MongoDatabase()user_service_mongo = UserService(mongo_db)user_service_mongo.get_user()
✅ 优势:
UserService
完全不关心用的是哪种数据库;- 测试时可以传入
MockDatabase
; - 扩展 MongoDB/PostgreSQL 不改原来的代码!
🧭 结构图(Mermaid)
🏁 总结一句话
依赖倒置原则让系统依赖“接口而不是实现”,从而实现模块解耦、系统灵活、扩展容易。
📌 实战应用场景
- 工厂模式
- Web框架中的 服务注册+依赖注入
- 测试时用 Mock 替换真实实现
- 插件化系统:核心代码依赖统一接口,插件各自实现
如果你想,我还能帮你加一个 “依赖注入容器(IoC)”的Python简易实现,进一步升级你的架构能力,要吗?🚀
相关文章:
依赖倒置原则
当然可以!这次我们来详细讲解 依赖倒置原则(DIP: Dependency Inversion Principle),它是 SOLID 五大设计原则中的压轴,也是最关键的“架构型原则”。 我将从: 什么是依赖倒置原则(定义&#x…...
PostgreSQL 的 VACUUM 与 VACUUM FULL 详解
PostgreSQL 的 VACUUM 与 VACUUM FULL 详解 一、基本概念对比 特性VACUUMVACUUM FULL定义常规维护操作,清理死元组激进重组操作,完全重写表数据锁级别不阻塞读写(共享锁)排他锁(阻塞所有操作)空间回收只标记空间为可用,不返还OS空间返还操作…...
SQL面试题——留存分析之使用bitmap 计算留存
使用bitmap 计算留存 之前我们说过,留存分析其实在企业数据分析中,是很基础但是也很重要的,留存分析可以反映产品的发展是否健康,是否可持续发展,之前我们介绍过,可以看看之前的文章 SQL面试题——留存分析 因为使用工具的限制,所以我们实现方式也会有所不同,之前我们…...
P2415集合求和 题解
P2415 集合求和 题解 公式推导: 设集合有 n 个元素,记为 a 1 , a 2 , … , a n a_1, a_2, \dots, a_n a1,a2,…,an。 每个子集要么包含某个元素,要么不包含。 我们固定某个元素 a k a_k ak,再从剩下的 n − 1 n -…...
【2025年五一数学建模竞赛】C题 完整论文 模型建立与求解
目录 2025年五一数学建模竞赛 C题完整论文:建模与求解 Matlab代码一、问题重述二、模型假设与符号说明2.1 模型基本假设2.2 符号说明 问题一:预测博主新增关注数问题二:预测用户的新关注行为问题三:预测用户在线状态及互动博主问题…...
wpf 输入框 在输入时去除水印
wpf ScrollViewer 在输入数据时去除水印 在WPF(Windows Presentation Foundation)中,ScrollViewer控件通常用于显示滚动内容。如果你想在ScrollViewer中使用数据输入(例如文本输入),并且希望在输入时去除水…...
数字智慧方案5857丨智慧机场解决方案与应用(53页PPT)(文末有下载方式)
资料解读:智慧机场解决方案与应用 详细资料请看本解读文章的最后内容。 随着科技的飞速发展,智慧机场的建设已成为现代机场发展的重要方向。智慧机场不仅提升了旅客的出行体验,还极大地提高了机场的运营效率。本文将详细解读沃土数字平台在…...
C语言-指针(二)
一级指针 一级指针指的是存储了变量地址的指针 一级指针的变量类型是 类型 * 一级指针的类型与变量的类型有些不同 例:int * p 前面的int * 是该地址的类型 int a 0; int * p a; 这里的指针 p 就是一级指针 二级指针 指针变量也是变量因此也会有地…...
React 组件prop添加类型
给函数的props做注解 import { useState } from reacttype Props { className:string,title?:string } // 自定义一个Button组件 function Button(props:Props){// 解构出classname\const {className} propsreturn <button className{className}>点击我</button&g…...
Spring Boot中集成Guava Cache或者Caffeine
一、在Spring Boot(1.x版本)中集成Guava Cache 注意: Spring Boot 2.x用户:优先使用Caffeine,性能更优且维护活跃。 1. 添加依赖 在pom.xml中添加Guava依赖: <dependency><groupId>com.google.guava</groupId&…...
全感官交互革命:当 AI 大模型学会 “看、听、说、创”
引言:从 “文字对话” 到 “全感官体验”,AI 正在重塑人类认知边界 当 AI 不再局限于文本对话,而是能 “看懂” 图像、“听懂” 语音、“生成” 视频,并将这些模态无缝融合时,一场关于人机交互的革命已然开启。DeepSe…...
Linux 库文件详解
Linux 库文件详解 一、库文件概述 库文件是预先编译好的方法的集合,它为程序员提供了一种方便的方式来复用代码。在 Linux 系统中,主要有两种类型的库文件:静态库和共享库。 静态库(.a 文件) 使用静态库࿰…...
蒙特卡罗方法(Monte Carlo Method):基于随机采样的数值计算与模拟技术
核心思想 蒙特卡罗方法通过随机采样和统计模拟解决数学、物理、工程等领域的复杂问题,其核心是利用大数定律——当样本量足够大时,样本均值会收敛于期望值。 关键特点: 无维度诅咒&#x…...
HTTPS协议:更安全的HTTP
目录 1. 前言 2. HTTP 与 HTTPS:安全的分水岭 2.1 HTTP 的安全隐患 2.2 HTTPS 的安全提升 3. HTTPS 的核心概念 3.1 加密三剑客:对称加密、非对称加密与哈希算法 3.2 SSL/TLS 握手过程:建立安全通道的关键步骤 3.3 数字证书ÿ…...
Flutter BottomNavigationBar 详解
目录 一、引言 二、BottomNavigationBar 的基本用法 三、主要属性 1. 基本配置 2. 导航项配置 3. 导航类型选择 四、高级功能实现 1. 结合 PageView 实现滑动切换 2. 添加徽章提示 3. 自定义凸起按钮(FAB融合) 4. 渐变背景实现 五、自定义 B…...
吴恩达深度学习作业 RNN模型——字母级语言模型
一. 简单复习一下RNN RNN RNN适用于处理序列数据,令是序列的第i个元素,那么就是一个长度为的序列,NLP中最常见的元素是单词,对应的序列是句子。 RNN使用同一个神经网络处理序列中的每一个元素。同时,为了表示序列的…...
数字时代,如何为个人信息与隐私筑牢安全防线?
首席数据官高鹏律师团队编著 在当今数字化时代,个人信息和隐私保护至关重要。我们在享受数字生活带来的便利时,也面临着个人信息泄露、隐私被侵犯的风险。下面将从先进技术和法律途径两个方面,探讨如何严格保护个人信息和隐私。 一、先进技…...
javascript交换值最好三种
代码 1. 位运算(性能高,但只能用于整数) var a15; var b32; console.log(a) //15 console.log(b) //32 a a ^ b; b a ^ b; a a ^ b; console.log(a) //32 console.log(b) //152. 数组结构(性能高,但要ES6) var a15; var b32; console.log(…...
C++-Lambda表达式
目录 1.什么是 Lambda? 2.例子:打印每个元素(和 for_each 一起用) 3.捕获外部变量(Capture) 3.1. 捕获值(拷贝):[] 3.2. 捕获引用:[&] 3.3. 指定捕…...
逻辑回归的多分类实战:以鸢尾花数据集为例
文章目录 引言:从二分类到多分类一、多分类问题无处不在二、One-vs-All策略揭秘1. 核心思想2. 数学表达 三、鸢尾花分类完整实现1. 环境准备2. 数据加载与探索3. 数据预处理4. 模型训练与评估5. 决策边界可视化 四、关键参数解析五、总结 引言:从二分类到…...
[面试]SoC验证工程师面试常见问题(一)
SoC验证工程师面试常见问题(一) 摘要:在面试 SoC 验证工程师职位时,面试官通常会重点考察候选人对 SystemVerilog 和 UVM (Universal Verification Methodology) 的掌握程度,因为这两者是现代 IC 验证的核心技能。以下是可能会被问到的常见问题,涵盖 SystemVerilo…...
传统银行服务和 区块链支付无缝融合的一种解决方案
Dragonfly Capital 的合伙人 Alex Pack 曾表示:“DeFi 的目标是重构全球银行体系,并打造开放且无须许可的经营环境。”在 DeFi 的金融世界中,加密资产架构在区块链上,通过各个协议实现资产之间的高效转移和价值的实时流通,如 Metamask 钱包的自托管,Uniswap 的资产交易,…...
大语言模型能力评定探讨
有标准答案的评估(选择题) 评估语言模型能力的基本思路是准备输入和标准答案,比较不同模型对相同输入的输出 由于AI答题有各种各样答案,因此现在是利用选择题考察。 有一个知名的选择题的基准叫做Massive Multitask Language Und…...
解构区块链身份认证:从ID到零知识证明的实战指南
引言 在数字经济高速发展的今天,数字身份已成为个人与数字世界交互的核心凭证。传统中心化身份系统存在数据孤岛、隐私泄露、单点故障等痛点,而区块链技术凭借去中心化、不可篡改、可追溯的特性,为数字身份验证提供了革命性解决方案…...
IntelliJ IDEA 使用教程
文章目录 一、创建项目二、创建模块三、创建包四、创建类五、编写代码六、运行代码注意 一、创建项目 二、创建模块 【File】->【New】->【Module…】 三、创建包 【helloword】->【右击 src】->【New】->【Package】 四、创建类 【helloword】->【s…...
HBM的哪些事
命令操作 这也许是DDR往HBM演进的一些奇淫技巧。 本篇内容属于杂谈,关于HBM的奇淫技巧,随后出专题介绍。...
C++ std::initializer_list 详解
std::initializer_list 是 C11 引入的一个轻量级模板类,用于支持花括号初始化列表({1, 2, 3})的语义。它允许函数或构造函数接受任意长度的同类型初始化列表,是实现统一初始化({} 语法)的核心组件。 1. 基本…...
网络原理 - 13(HTTP/HTTPS - 4 - HTTPS)
目录 HTTPS 是什么 不得不的策略 - 应对“运营商劫持” “加密” 是什么 分类 对称加密 非对称加密 HTTPS 工作原理 1)引入对称加密 2) 引入非对称加密 中间人攻击 引入证书 证书的验证过程 完! HTTPS 是什么 HTTPS 也是一个应…...
当MCP撞进云宇宙:多芯片封装如何重构云计算的“芯“未来?
当MCP撞进云宇宙:多芯片封装如何重构云计算的"芯"未来? 2024年3月,AMD发布了震撼业界的MI300A/B芯片——这颗为AI计算而生的"超级芯片",首次在单封装内集成了13个计算芯片(包括3D V-Cache缓存、CDNA3 GPU和Zen4 CPU),用多芯片封装(Multi-Chip Pac…...
Kotlin Flow流
一 Kotlin Flow 中的 stateIn 和 shareIn 一、简单比喻理解 想象一个水龙头(数据源)和几个水杯(数据接收者): 普通 Flow(冷流):每个水杯来接水时,都要重新打开水龙头从…...
虚拟局域网(VLAN)实验(Cisco Packet Tracer)-路由器、交换机的基本配置
好的,我们来根据你提供的文档,一步步地在 Cisco Packet Tracer 中完成这个跨交换机划分 VLAN 的实验。 实验目标: 配置两台交换机 SW1 和 SW2,划分 VLAN 10 和 VLAN 20,配置 Trunk 链路,并测试同 VLAN 和跨 VLAN 的连…...
【论文速递】2025年09周 (Robotics/Embodied AI/LLM)
目录 LLM-Microscope:揭示标点符号在Transformers的上下文中的隐藏作用英文摘要中文摘要 SurveyX:通过大型语言模型实现学术调查自动化英文摘要中文摘要 数学推理的自我奖励校正英文摘要中文摘要 VideoGrain:调整时空关注以进行多元透明视频编…...
自主机器人模拟系统
一、系统概述 本代码实现了一个基于Pygame的2D自主机器人模拟系统,具备以下核心功能: 双模式控制:支持手动控制(WASD键)和自动导航模式(鼠标左键设定目标) 智能路径规划:采用改进型…...
DeepSeek构建非农预测模型:量化关税滞后效应与非线性经济冲击传导
AI分析:非农数据前瞻与关税影响的滞后性 根据AI模型对多维度经济指标的交叉验证,4月非农就业报告或呈现“增速放缓但未失速”的特征。当前市场共识预期为新增就业13.3万人(前值22.8万),失业率维持4.2%,时薪…...
前端面经-VUE3篇--vue3基础知识(一)插值表达式、ref、reactive
一、计算属性(computed) 计算属性(Computed Properties)是 Vue 中一种特殊的响应式数据,它能基于已有的响应式数据动态计算出新的数据。 计算属性有以下特性: 自动缓存:只有当它依赖的响应式数据发生变化时ÿ…...
云原生后端架构的优势与最佳实践
📝个人主页🌹:慌ZHANG-CSDN博客 🌹🌹期待您的关注 🌹🌹 在过去的几年里,随着云计算和容器化技术的迅猛发展,云原生架构逐渐成为现代企业和开发团队构建和运维应用系统的首选方式。云原生架构通过高度的自动化、弹性伸缩、微服务化等特点,使得企业能够在不断变化…...
力扣838.推多米诺随笔
“生活就像海洋,只有意志坚强的人,才能到达彼岸。”—— 马克思 题目 n 张多米诺骨牌排成一行,将每张多米诺骨牌垂直竖立。在开始时,同时把一些多米诺骨牌向左或向右推。 每过一秒,倒向左边的多米诺骨牌会推动其左侧…...
aab转apk
一、 android34升级: 1、升级到安卓34(蓝牙、图片) 再蓝牙广播的地方加入Context.RECEIVER_EXPORTED 2、废弃了 BluetoothAdapter#enable() 和 BluetoothAdapter#disable(),需要修改 // 以前的蓝牙操作BluetoothManager bluetoo…...
LeetCode 560. 和为 K 的子数组 | 前缀和与哈希表的巧妙应用
文章目录 方法思路:前缀和 哈希表核心思想关键步骤 代码实现复杂度分析示例解析总结 题目描述 给定一个整数数组 nums 和一个整数 k,请统计并返回该数组中和为 k 的子数组的数量。 子数组是数组中连续的非空元素序列。 示例 输入:nums …...
【Hive入门】Hive性能调优:小文件问题与动态分区合并策略详解
目录 引言 1 Hive小文件问题概述 1.1 什么是小文件问题 1.2 小文件产生的原因 2 Hive小文件合并机制 2.1 hive.merge.smallfiles参数详解 2.2 小文件合并流程 2.3 合并策略选择 3 动态分区与小文件问题 3.1 动态分区原理 3.2 动态分区合并策略 3.3 动态分区合并流程…...
基于Springboot+Vue3.0的前后端分离的个人旅游足迹可视化平台
文章目录 0、前言1、前端开发1.1 登录注册页面1.2 首页1.3 足迹管理1.3.1 足迹列表1.3.2 添加足迹1.4 个人中心1.4.1 足迹成就1.4.2 个人信息1.4.3 我的计划2、后端开发2.1 用户接口开发2.2 足迹点接口2.3 旅游计划接口3、完整代码资料下载0、前言 项目亮点: 前端用户权限动态…...
安妮推广导航系统开心版多款主题网址推广赚钱软件推广变现一键统计免授权源码Annie
一、源码描述 这是一套推广导航源码(Annie),基于Funadmin框架(ThinkPHP8Layui ),内置多款主题,可以用于网址推广,或者用于软件推广,PC端软件手机端软件,后台…...
单片机-STM32部分:1、STM32介绍
飞书文档https://x509p6c8to.feishu.cn/wiki/CmpZwTgHhiQSHZkvzjdc6c4Yn1g STM32单片机不是一款芯片,而是一个系列的芯片? STM32系列单片机是ST(意法半导体)公司开发的一套32位微控制器基于Arm Cortex()-M处理器,它包…...
PHP-session
PHP中,session(会话)是一种在服务器上存储用户数据的方法,这些数据可以在多个页面请求或访问之间保持。Session提供了一种方式来跟踪用户状态,比如登录信息、购物车内容等。当用户首次访问网站时,服务器会创…...
php artisan resetPass 执行密码重置失败的原因?php artisan resetPass是什么 如何使用?-优雅草卓伊凡
php artisan resetPass 执行密码重置失败的原因?php artisan resetPass是什么 如何使用?-优雅草卓伊凡 可能的原因 命令不存在:如果你没有正确定义这个命令,Laravel 会报错而不是提示”重置密码失败”用户不存在:’a…...
AI大模型-微调和RAG方案选项
在搭建知识库的方向上,有两个落地方案:微调、RAG。两个方案的比对: 方案选型 微调 让大模型(LLM)去学习现有知识(调整大模型的参数,让它学习新的知识),最终生成一个新的…...
MySQL 第一讲---基础篇 安装
前言: 在当今数据驱动的时代,掌握数据库技术已成为开发者必备的核心技能。作为全球最受欢迎的开源关系型数据库,MySQL承载着淘宝双十一每秒50万次的交易请求,支撑着Facebook百亿级的数据存储,更是无数互联网企业的数据…...
【JavaScript-Day 1】从零开始:全面了解 JavaScript 是什么、为什么学以及它与 Java 的区别
Langchain系列文章目录 01-玩转LangChain:从模型调用到Prompt模板与输出解析的完整指南 02-玩转 LangChain Memory 模块:四种记忆类型详解及应用场景全覆盖 03-全面掌握 LangChain:从核心链条构建到动态任务分配的实战指南 04-玩转 LangChai…...
C++ 复习
VS 修改 C 语言标准 右键项目-属性 输入输出 //引用头文件,用<>包裹起来的一般是系统提供的写好的代码 编译器会在专门的系统路径中去进行查找 #include <iostream> //自己写的代码文件一般都用""包裹起来 编译器会在当前文件所在的目录中査…...
数字智慧方案5877丨智慧交通项目方案(122页PPT)(文末有下载方式)
篇幅所限,本文只提供部分资料内容,完整资料请看下面链接 https://download.csdn.net/download/2301_78256053/89575494 资料解读:智慧交通项目方案 详细资料请看本解读文章的最后内容。 智慧交通项目方案是一个全面的设计框架,…...