Python 面向对象 - 依赖倒置原则 (DIP)

在这里插入图片描述

1. 核心概念

依赖倒置原则(Dependency Inversion Principle, DIP) 是SOLID原则中的"D",包含两个关键点:

  1. 高层模块不应依赖低层模块,二者都应依赖抽象
  2. 抽象不应依赖细节,细节应依赖抽象

2. 使用场景

典型应用场景

  • 系统需要支持多种实现方式
  • 模块间需要解耦
  • 需要进行单元测试(依赖mock对象)
  • 系统可能面临实现方式的变更

反模式示例

class LightBulb:  # 低层模块def turn_on(self):print("Bulb turned on")def turn_off(self):print("Bulb turned off")class Switch:     # 高层模块def __init__(self):self.bulb = LightBulb()  # 直接依赖具体实现def operate(self):self.bulb.turn_on()

3. 最佳实践

正确实现方式

from abc import ABC, abstractmethod# 抽象接口
class Switchable(ABC):@abstractmethoddef turn_on(self):pass@abstractmethoddef turn_off(self):pass# 低层模块实现接口
class LightBulb(Switchable):def turn_on(self):print("LED bulb turned on")def turn_off(self):print("LED bulb turned off")class Fan(Switchable):def turn_on(self):print("Fan started spinning")def turn_off(self):print("Fan stopped")# 高层模块依赖抽象
class Switch:def __init__(self, device: Switchable):  # 依赖抽象self.device = devicedef operate(self):self.device.turn_on()# 使用示例
bulb = LightBulb()
switch = Switch(bulb)
switch.operate()fan = Fan()
fan_switch = Switch(fan)
fan_switch.operate()

关键优点

  1. 可扩展性:轻松添加新设备类型
  2. 可测试性:可以创建测试用的mock对象
  3. 低耦合:Switch类不依赖具体设备实现
  4. 可维护性:设备实现变化不会影响Switch类

4. Python特有实现方式

使用协议(Protocol)实现

Python 3.8+ 可以使用更灵活的协议实现:

from typing import Protocolclass Switchable(Protocol):def turn_on(self) -> None: ...def turn_off(self) -> None: ...class SmartTV:# 不需要显式继承,只需要实现协议方法def turn_on(self):print("TV powered on")def turn_off(self):print("TV powered off")# 同样可以工作
tv = SmartTV()
tv_switch = Switch(tv)
tv_switch.operate()

5. 实际应用建议

  1. 适度使用:简单场景不必过度设计
  2. 结合DI容器:在大型项目中可使用依赖注入框架
  3. 接口设计:保持抽象接口小而专注(ISP原则)
  4. 文档说明:对抽象接口进行充分文档说明

6. 常见误区

❌ 为每个类都创建接口
✅ 只为确实需要多实现的模块创建抽象

❌ 抽象接口包含太多方法
✅ 遵循接口隔离原则(ISP)

❌ 认为DIP就是依赖注入(DI)
✅ DI是实现DIP的一种技术手段

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

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

相关文章

centos7 yum install docker 安装错误

1、错误信息: [rootlocalhost atguigu]# yum install docker 已加载插件:fastestmirror, langpacks Repository base is listed more than once in the configuration Loading mirror speeds from cached hostfile Could not retrieve mirrorlist http:…

【Gorm】模型定义

intro package mainimport ("gorm.io/gorm""gorm.io/driver/sqlite" // GORM 使用该驱动来连接和操作 SQLite 数据库。 )type Product struct {gorm.Model // 嵌入GORM 内置的模型结构,包含 ID、CreatedAt、UpdatedAt、DeletedAt 四个字段Cod…

R语言从专家到小白

文章目录 下载安装R下载安装R StudioCRAN 下载安装R Index of /bin https://cran.r-project.org/ 下载安装R Studio https://posit.co/download/rstudio-desktop/ CRAN R综合档案网络。 CRAN 镜像是一个提供 R 语言软件和包的在线服务,用户可以从不同的地区选择…

Java的Selenium的特殊元素操作与定位之时间日期控件

分为两种情况: 控件没有限制手动输入,则直接调用sendKeys方法写入时间数据 //时间日期控件处理 chromeDriver.get ("https://www,fliggy,com/?ttidsem.000000736&hlreferidbaidu.082076&route sourceseo"); chromeDriver.findElement (By.xpat…

38常用控件_QWidget的enable属性(2)

实现用另一个按钮切换之前按钮的“可用”状态 在同一个界面中,要求不同的控件的 objectName 也是必须不同的.(不能重复) 后续就可以通过 ui->objectName 方式来获取到对应的控件对象了 ui->pushButton // 得到了第一个按钮对应的对象 ui->pushButton 2 //…

【Linux学习笔记】初识进程概念和进程PCB

【Linux学习笔记】初识冯诺依曼体系和进程PCB 🔥个人主页:大白的编程日记 🔥专栏:Linux学习笔记 文章目录 【Linux学习笔记】初识冯诺依曼体系和进程PCB前言一. 冯诺依曼体系结构1.1 关于冯诺依曼体系的要点: 二. 操…

7.3 主成分分析(PCA)

一、协方差矩阵 这节是介绍 SVD 在统计和数据分析中的一个主要应用,即主成分分析。例子来自于人类的基因组,脸部识别和金融,目的是理解一个大的数据矩阵(测量值)。对于 n n n 个样本,我们每个测量 m m m…

anaconda安装使用+pytorch环境配置(cpu)+pycharm环境配置(详细教程)

一、anaconda下载 1.anaconda官网尝试下载: 官网网址:Anaconda | Built to Advance Open Source AI 1.进入官网 2.点击Products->Distribution,跳过注册进入下载页面 3.选择系统下载 2.清华镜像下载 1.网址:Index of /anac…

Unity3D仿星露谷物语开发34之单击Drop项目

1、目标 当在道具栏中选中一个Item时,点击地面就可以实现Item的drop操作,每点击一次就drop一次,直到道具栏中Item数量不够。 这样的好处:避免每次Drop都从道具栏中拖拉Item,通过点击这种操作可以更加高效。 方法&am…

java 正则表达式优化

1,什么是正则表达式 正则表达式使用一些特定的元字符来检索、匹配以及替换符合规则的字符串。 构造正则表达式语法的元字符,由普通字符、标准字符、限定字符(量词)、定位字符(边界字符)组成 普通字符 字母[…

检测链表是否有环, 动画演示, Floyd判圈算法扩展应用

力扣原题链接: 141. 环形链表 - 力扣(LeetCode) 哈希表 检测环形链表, 直观的思路就是使用哈希表, 遍历这个链表, 将访问过的节点加入到哈希表中, 如果遍历过程中发现节点已经存在于哈希表中, 则说明链表有环. 复杂度分析: 时间复杂度: O(N), 最坏情…

linux专题3-----linux上链接远程mysql

要在 Ubuntu 上连接远程 MySQL 数据库,你可以使用 MySQL 客户端工具或者其他数据库管理工具,如 phpMyAdmin 或 MySQL Workbench。以下是使用 MySQL 命令行工具连接远程 MySQL 的步骤: 确保已安装 MySQL 客户端 首先,确保你的 Ub…

webpack js 逆向 --- 个人记录

网站 aHR0cDovL2FlcmZheWluZy5jb20v加密参数 参数加密位置 方法: 1. 构造自执行函数 !function(e) {// 加载器 }(// 模块1;// 模块2 )2. 找到js的加载器 3. 把上述代码放入第一步构造的自执行函数(完整扣取一整个加载器里的代码),并用一…

用HTML.CSS.JavaScript实现一个贪吃蛇小游戏

目录 一、引言二、实现思路1. HTML 结构2. CSS 样式3. JavaScript 逻辑 三、代码实现四、效果展示 一、引言 贪吃蛇是一款经典的小游戏,曾经风靡一时。今天,我们将使用 HTML、CSS 和 JavaScript 来实现一个简单的贪吃蛇小游戏。通过这个项目&#xff0c…

基于α-β剪枝的含禁手AI五子棋

前言: 正常的五子棋应当设有禁手规则,否则先手黑棋必赢,基于此点设计出一款包含禁手的AI五子棋项目,该项目代码已在github开源,感兴趣的友友可以自取试玩:ace-trump-tech/AI-Gomoku-with-Prohibition-Moves: 含禁手的A…

Spring Boot 集成 Redis中@Cacheable 和 @CachePut 的详细对比,涵盖功能、执行流程、适用场景、参数配置及代码示例

以下是 Cacheable 和 CachePut 的详细对比,涵盖功能、执行流程、适用场景、参数配置及代码示例: 1. 核心对比表格 特性CacheableCachePut作用缓存方法的返回结果,避免重复计算执行方法并更新缓存,不覆盖原有缓存执行流程缓存命中…

可以使用费曼学习法阅读重要的书籍

书本上画了很多线,回头看等于没画出任何重点。 不是所有的触动都是有效的。就像你曾经看过很多好文章,当时被触动得一塌糊涂,还把它们放进了收藏夹,但一段时间之后,你就再也记不起来了。如果让你在一本书上画出令自己…

Nginx之https重定向为http

为了将Nginx中443端口的请求重定向到80端口,你可以按照以下步骤进行操作: ‌确认Nginx已经正确安装并运行‌: 确保Nginx服务已经在你的系统上安装并运行。你可以通过运行以下命令来检查Nginx的状态(具体命令可能因操作系统而异&a…

【ARTS】【LeetCode-2873】有序三元组中的最大值!

前言 仅做学习使用,侵删 什么是ARTS? 算法(Algorithm): 每周至少一道LeetCode算法题,加强编程训练和算法学习 阅读(Review): 阅读并点评至少一篇英文技术文章,提高英文水平 技巧 (Tip):学习至少一个技…

基于spring boot 鲜花销售系统PPT(源码+lw+部署文档+讲解),源码可白嫖!

课题意义 随着网络不断的普及发展,鲜花销售系统依靠网络技术的支持得到了快速的发展,首先要从用户的实际需求出发,通过了解用户的需求开发出具有针对性的信息管理系统,利用目前网络给用户带来的方便快捷这一特点对系统进行调整&am…