3 设计模式原则之依赖倒置原则

ops/2024/11/19 12:51:03/

 一、依赖倒置原则

1.定义

        高层模块不应该依赖低层模块,两者都应该依赖其抽象;

        抽象不应该依赖细节,细节应该依赖抽象。

        简单的说:面向接口编程,而不是面向实现编程。通过依赖于抽象,系统可以更加灵活、易于扩展和维护。

2.代码举例 

  • 接口定义
    • CpuDiskMemory 是三个接口,分别定义了 runsavegetsave 方法。
  • 实现类
    • IntelCpu 实现了 Cpu 接口。
    • ChangChengDisk 实现了 Disk 接口。
    • KingstonMemory 实现了 Memory 接口。
  • 计算机类 Computer
    • Computer 类通过 set 方法注入 CPU、硬盘和内存,使用接口作为参数类型。
  • 客户端代码 ComputerDemo
    • ComputerDemo 创建了具体的组件实例,并将它们注入到 Computer 中进行使用。
java">public interface Cpu {public void run();
}public interface Disk {//存储数据public void save(String data);//读取数据public String get();}public interface Memory {public void save();
}public class IntelCpu implements Cpu{@Overridepublic void run() {System.out.println("Intel的Cpu运行了");}
}public class ChangChengDisk implements Disk{@Overridepublic void save(String data) {System.out.println("使用长城硬盘存储数据");}@Overridepublic String get() {System.out.println("使用长城硬盘读取数据");return "数据";}
}public class KingstonMemory implements Memory{@Overridepublic void save() {System.out.println("使用kingston的内存条");}
}public class Computer {private Memory memory;private Disk disk;private Cpu cpu;public Memory getMemory() {return memory;}public void setMemory(Memory memory) {this.memory = memory;}public Disk getDisk() {return disk;}public void setDisk(Disk disk) {this.disk = disk;}public Cpu getCpu() {return cpu;}public void setCpu(Cpu cpu) {this.cpu = cpu;}public void run(){System.out.println("计算器执行!");String data = disk.get();System.out.println("从硬盘上获取的数据是:"+data);cpu.run();memory.save();}
}public class ComputerDemo {public static void main(String[] args) {Disk disk = new ChangChengDisk();Cpu cpu = new IntelCpu();Memory memory = new KingstonMemory();Computer computer = new Computer();computer.setCpu(cpu);computer.setDisk(disk);computer.setMemory(memory);computer.run();}
}

3.代码讲解

(1)Computer 类依赖于抽象(接口),而不是具体实现

  • Computer 类中,CpuDiskMemory 都是接口类型。这意味着 Computer 类并不知道具体的实现类(如 IntelCpuChangChengDiskKingstonMemory),而是依赖于这些接口。
  • 依赖倒置原则体现
    • 高层模块(Computer) 依赖于 抽象接口(Cpu、Disk、Memory),而不是具体实现。这使得 Computer 类与具体组件之间解耦,可以方便地替换不同的硬件实现。

(2)实现类依赖于抽象,而不是相互依赖

  • IntelCpuChangChengDiskKingstonMemory 类都实现了各自对应的接口。
  • 依赖倒置原则体现
    • 具体实现类 依赖于接口(如 CpuDiskMemory),而不是直接依赖于 Computer 类。这保证了不同的实现类可以独立发展,而不会影响到计算机系统的设计。

(3)客户端代码灵活性

  • 客户端可以自由地选择不同的硬件实现(比如替换 ChangChengDiskSamsungDisk,替换 IntelCpuAMDCpu),而无需修改 Computer 类的任何代码。
  • 依赖倒置原则体现
    • 客户端通过接口进行依赖注入,而不是直接依赖具体类。这样就可以很方便地替换不同的实现,而不会影响整体系统的功能。

4. 改进点:依赖注入方式

目前,使用的是 Setter 注入setCpusetDisksetMemory 方法)。在实际开发中,我们还有其他的 依赖注入 方式,如:

  • 构造器注入
    • 在创建 Computer 实例时,通过构造器注入所需的硬件组件,可以确保这些组件不会为空。
  • 接口注入
    • 通过接口定义注入的方法,保证 Computer 类能够灵活注入不同的组件。

5.总结

  • 高层模块(Computer 类) 依赖于 抽象(接口),而不是具体实现。这使得 Computer 类能够在不修改自身代码的情况下,适应不同的硬件组件。
  • 低层模块(IntelCpu、ChangChengDisk、KingstonMemory 类) 实现了对应的接口(Cpu、Disk、Memory),符合 "低层模块依赖于抽象" 的原则。
  • 灵活性与可扩展性:这种设计模式使得系统具有很强的扩展性,能够轻松地替换不同的实现,如使用新的 AMD CPU 或 SamsungDisk,而无需修改核心 Computer 类的逻辑。

http://www.ppmy.cn/ops/134973.html

相关文章

【C++之STL】摸清 string 的模拟实现(上)

文章目录 1. 为什么要模拟实现?2. 基本框架搭建3. 构造函数3. 1 默认构造/from c_str3. 2 拷贝构造3. 2. 1 深浅拷贝 3. 3 fill3. 4 迭代器区间构造 4. 容量操作4. 1 size()和capacity()和empty()4. 2 clear()4. 3 resize()4. 4 reserve() 1. 为什么要模拟实现&…

【Electron】总结:如何创建Electron+Element Plus的项目

目录 一、准备环境 二、创建Element项目 三、添加依赖 四、配置页面 五、安装Element-plus 六、配置页面 七、生成安装包 八、增加支持TypeScript 我将结合官网手册与AI问到的信息,直接给出步骤,与命令。 一、准备环境 首先在C盘Users&#xf…

游戏引擎学习第九天

视频参考:https://www.bilibili.com/video/BV1ouUPYAErK/ 修改之前的方波数据,改播放正弦波 下面主要讲关于浮点数 1. char(字符类型) 大小:1 字节(8 位)表示方式:char 存储的是一个字符的 A…

数据结构——重排链表(经典题目,涉及三个知识点)

一、示例 二、上代码 class Solution { public:void reorderList(ListNode* head) {if (head nullptr || head->next nullptr) return;ListNode* mid FindMiddleNode(head); // 找到中间节点ListNode* l1 head;ListNode* l2 mid->next;mid->next nullptr;l2…

shell中的case语句和循环语句

文章目录 🍊自我介绍🍊shell中的case语句匹配常量匹配变量匹配字符串列表 🍊循环语句while 循环for 循环单词表通过逐个列出单词通过变量中的数据通过命令行传输单词表 你的点赞评论就是对博主最大的鼓励 当然喜欢的小伙伴可以:点…

基于单片机的风能太阳能供电的路灯智能控制系统设计(论文+源码)

1系统总体设计 本课题为风能太阳能供电的路灯智能控制系统设计,系统的主要功能设计如下: (1) 供电模块:采用太阳能板以及风机模拟风扇充电,经过充电电路给锂电池进行充电。再由锂电池给照明模块以及整个项…

pxe自动装机(centos)

概述 PXE(Preboot Execution Environment)是一种允许计算机通过网络启动自己的操作系统的技术。它允许计算机在缺少本地存储设备或操作系统的情况下,从远程服务器上下载并执行操作系统。PXE通常用于无盘站点或远程支持,可以通过网…

Java进阶(JVM)

Java进阶(一) 一. JVM 1.1 为什么学习JVM 首先面试需要 高级程序员也更需要了解JVM 1.2 JVM作用 JVM负责把编译后的字节转换为机器码 1.3 JVM内部构造 1.3.1 类加载部分: 负责把硬盘上字节码加载到内存中(运行时数据区) 1.3.2 运行时数据区: …