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

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

 一、依赖倒置原则

1.定义

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

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

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

2.代码举例 

  • 接口定义
    • CpuDiskMemory 是三个接口,分别定义了 runsavegetsave 方法。
  • 实现类
    • IntelCpu 实现了 Cpu 接口。
    • ChangChengDisk 实现了 Disk 接口。
    • KingstonMemory 实现了 Memory 接口。
  • 计算机类 Computer
    • Computer 类通过 set 方法注入 CPU、硬盘和内存,使用接口作为参数类型。
  • 客户端代码 ComputerDemo
    • ComputerDemo 创建了具体的组件实例,并将它们注入到 Computer 中进行使用。
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{
    @Override
    public void run() {
        System.out.println("Intel的Cpu运行了");
    }
}

public class ChangChengDisk implements Disk{
    @Override
    public void save(String data) {
        System.out.println("使用长城硬盘存储数据");
    }

    @Override
    public String get() {
        System.out.println("使用长城硬盘读取数据");
        return "数据";
    }
}

public class KingstonMemory implements Memory{
    @Override
    public 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.kler.cn/a/401307.html

相关文章:

  • VSCode+ESP-IDF开发ESP32-S3-DevKitC-1(2)第一个工程 LED心跳灯
  • python画图|3D errorbars基础教程
  • Java通过calcite实时读取kafka中的数据
  • hadoop3.x 新特性
  • Spring 与 Spring MVC 与 Spring Boot三者之间的区别与联系
  • 大语言模型通用能力排行榜(2024年11月8日更新)
  • RNN公式解释:实现记忆功能;RNN的状态向量
  • 如何在matlab中将数据打印到csv格式文件中?
  • Eclipse 创建Dynamic web project项目-配置Tomcat服务器
  • 如何利用AI提高测试覆盖率?
  • JAVA中CountDownLatch使用方法
  • 计算机毕业设计Python+大模型中医养生问答系统 知识图谱 医疗大数据 中医可视化 机器学习 深度学习 人工智能 大数据毕业设计
  • 【Python】爬虫实战:高效爬取电影网站信息指南(涵盖了诸多学习内容)
  • Flink vs Spark
  • 矢量拟合(2) - Vector Fitting算法原理
  • ROM修改进阶教程------安卓14去除修改系统应用后导致的卡logo验证步骤 适用安卓13 14 安卓15可借鉴参考
  • 视频号直播自动回复功能,浏览器自动化插件vx llike620
  • 使用FFmpeg实现视频与GIF的画中画效果
  • golang开发一个海盗王的登录更新器
  • 大模型投喂私有化的数据
  • 【JavaSE】【多线程】阻塞队列
  • Go语言中的错误嵌套
  • Elasticsearch面试内容整理-搜索与查询
  • 大数据-225 离线数仓 - 目前需求分析 指标口径 日志数据采集 taildir source HDFS Sink Agent Flume 优化配置
  • 【GNU】gcc -O编译选项 -Og -O0 -O1 -O2 -O3 -Os
  • 字符串地址解析 省市区