当前位置: 首页 > ai >正文

设计模式 - 反转原则:DIP(Dependence Inversion Principle)最佳实践

文章目录

  • 引言
  • 1. DIP 的核心概念与现实类比
  • 2. DIP 的原始定义拆解
  • 3. 为什么要使用 DIP?
  • 4. 实践演示:四种设计演化
    • 设计一:完全耦合
    • 设计二:仅高层接口化(常见误区)
    • 设计三:低高双向抽象(实现 DIP)
    • 设计四:分包与框架注入
  • 5. 扩展:IoC、DI、IoC 容器 与 DIP 的区别

在这里插入图片描述

引言

在设计模式 - 面向对象原则:SOLID最佳实践我们了解了 SOLID 五大原则,但其中“依赖反转原则(DIP)”常被误用甚至混淆。

实际上,在项目中或许已经在践行它,只是没有深入理解其“反转控制”的真意。接下来将从现实类比到原理拆解,再到代码演化示例,彻底搞清 DIP,让它在开发工作中发挥更大作用。


1. DIP 的核心概念与现实类比

  • 现实类比:电商时代交易

    • 强耦合:买家当面付款 → 卖家交货,双方必须见面,耦合度高

    • 依赖反转:银行担保模型

      1. 买家先将钱付给银行
      2. 银行通知卖家发货
      3. 买家验货无误后,银行再支付给卖家
    • 原理:买卖双方不再直接依赖彼此,而是共同依赖“银行”这一标准化中介接口

  • 软件类比:浏览器与 Web 服务器

    • 浏览器(高层组件)不直接依赖某个特定 Web 服务器实现(低层组件),只依赖 HTTP 协议(抽象)。
    • 只要服务端遵循 HTTP 标准,就能与任意浏览器交互。

2. DIP 的原始定义拆解

“高级组件不应依赖于低级组件,两者都应依赖抽象;抽象不应该依赖实现,实现应该依赖抽象。”

  • 高级 vs 低级组件

    • 按调用层级区分,不代表功能复杂度高低。
    • 例:油门(高级)调用引擎(低级);应用程序(高层)调用操作系统(低层)。
  • 依赖抽象的意义

    • 消除组件变化对彼此的影响,保证双方只能在抽象约束范围内变动。
    • 如油门形状或引擎材质变化,都不影响“加减油”这一抽象接口。

3. 为什么要使用 DIP?

  1. 控制代码变化影响范围

    • 当外部系统需求变更,若双方通过统一抽象接口通信,只要接口不变,内部实现可随意调整,无需改动调用方代码。
  2. 提升可读性和可维护性

    • 统一抽象让职责清晰:相同功能集中定义在接口所在处,维护者无需跳转到各处定制逻辑,阅读和扩展更加顺畅。

4. 实践演示:四种设计演化

设计一:完全耦合

public class StringProcessor {private final StringReader stringReader;   // 具体类private final StringWriter stringWriter;   // 具体类public StringProcessor(StringReader stringReader, StringWriter stringWriter) {this.stringReader = stringReader;this.stringWriter = stringWriter;}public void readAndWrite() {stringWriter.write(stringReader.getValue());}public static void main(String[] args) {StringReader sr = new StringReader();sr.read("1111111");StringWriter sw = new StringWriter();StringProcessor sp = new StringProcessor(sr, sw);sp.readAndWrite();}
}
  • 优点:逻辑直接,编码简单
  • 缺点:高度耦合,低级组件修改必然影响高级组件

设计二:仅高层接口化(常见误区)

public interface StringProcessor {void readAndWrite(StringReader stringReader, StringWriter stringWriter);
}public class StringProcessorImpl implements StringProcessor {@Overridepublic void readAndWrite(StringReader sr, StringWriter sw) {sw.write(sr.getValue());}
}
  • 改进:高层依赖抽象
  • 不足:低层依然是具体类,变化仍影响高级组件,未实现真正依赖反转

设计三:低高双向抽象(实现 DIP)

public interface StringReader {void read(String input);String getValue();
}public interface StringWriter {void write(String value);
}public class StringProcessorImpl implements StringProcessor {@Overridepublic void readAndWrite(StringReader sr, StringWriter sw) {sw.write(sr.getValue());}
}// 客户端
StringReader sr = new StringReaderImpl();
sr.read("333333");
StringWriter sw = new StringWriterImpl();
StringProcessor sp = new StringProcessorImpl();
sp.readAndWrite(sr, sw);
  • 特点:高级、低级组件均依赖抽象,控制权真正“反转”到接口层

设计四:分包与框架注入

public class SPTest {@Resourceprivate StringProcessor sp;@Resourceprivate StringReader sr;@Resourceprivate StringWriter sw;public void run() {sr.read("444444");sp.readAndWrite(sr, sw);}
}
  • 改进:接口与实现可分布在不同包或库中,使用 Spring 等 IoC 容器自动注入,进一步提升复用与解耦

5. 扩展:IoC、DI、IoC 容器 与 DIP 的区别

术语定义与 DIP 的关系
IoC (控制反转)设计原则,将对象创建与依赖控制交由第三方完成原理层面与 DIP 类似,关注“谁来控制”
DI (依赖注入)实现 IoC 的设计模式,将依赖通过构造/属性/方法注入到目标类中DIP 的具体实现手段
IoC 容器 (DI 容器)管理对象创建与生命周期、自动注入依赖的框架(如 Spring)支撑 DI 实现,帮助落地 DIP 与 IoC
DIP (依赖反转原则)高层不依赖低层,抽象不依赖实现;实现依赖抽象指导如何设计抽象层与依赖关系的顶层设计原则

在这里插入图片描述

http://www.xdnf.cn/news/15127.html

相关文章:

  • 手机识别数据集,2628张原始图片,支持yolo,coco json,pasical voc xml等格式的标注
  • Nginx 中的负载均衡策略
  • TensorFlow2 study notes[1]
  • NW710NW713美光固态闪存NW719NW720
  • 【每日刷题】回文数
  • c语言中的数组IV
  • 奇哥面试:RabbitMQ工作模式深度剖析与Spring整合MQ
  • Datawhale AI夏令营:基于带货视频评论的用户洞察挑战赛上分全攻略
  • 数据库系统的基础知识(三)
  • 【时时三省】(C语言基础)通过指针引用数组元素
  • Redis 分片集群
  • C++中的智能指针(1):unique_ptr
  • 《汇编语言:基于X86处理器》第7章 整数运算(2)
  • 星云穿越与超光速飞行特效的前端实现原理与实践
  • 上位机知识篇---Linux软硬链接
  • 用 ELK+Filebeat 提高50%问题排查效率,这套方案实测有效!
  • cnpm exec v.s. npx
  • Shader面试题100道之(81-100)
  • python之set详谈
  • LeetCode经典题解:128、最长连续序列
  • TCP服务器与客户端三种方法实现
  • Linux权限的概念
  • SM712.TCT Semtech TVS二极管——电子设备的终极电路守护
  • DNS(Domain Name System,域名系统)
  • 计算机毕业设计ssm晋中大学城校园论坛 SSM大学城学生社区互动管理平台 JavaWeb高校校园信息交流与服务系统
  • java底层的native和沙箱安全机制
  • 系统思考:多元胜过能力
  • 鸿蒙 Secure Boot 全流程解析:从 BootROM 到内核签名验证的实战指南
  • 2025 年值得尝试的 6 大内容管理系统 (CMS)
  • 【实用IP查询工具】IP数据云-IP地址查询离线库使用方案