Java设计模式—面向对象设计原则(三) -----> 依赖倒转原则DIP(完整详解,附有代码+案例)

文章目录

    • 3.3 依赖倒转原则(DIP)
      • 3.3.1概述
      • 3.3.2 案例

3.3 依赖倒转原则(DIP)

依赖倒转原则:Dependency Inversion Principle,DIP

3.3.1概述

高层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象。简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合。

3.3.2 案例

下面看一个例子来理解依赖倒转原则

【例】组装电脑

现要组装一台电脑,需要配件cpu,硬盘,内存条。只有这些配置都有了,计算机才能正常的运行。选择cpu有很多选择,如Intel,AMD等,硬盘可以选择希捷,西数等,内存条可以选择金士顿,海盗船等。

在这里插入图片描述

public class InterCpu {
    public void runCpu(){
        System.out.println("Inter的cpu正在运行...");
    }
}
====================================================
  public class KingstonMemory {
    public void saveMemory(){
        System.out.println("使用金士顿作为内存条...");
    }
}
====================================================
  public class XiJieHardDisk {
    public void saveDisk(String data){
        System.out.println("从硬盘获取的数据是:"+data);
    }
    public String  getData(){
        System.out.println("获取硬盘数据操作...");
        return "获取硬盘数据完成。";
    }
}
====================================================
  public class Computer {
    private XiJieHardDisk hardDisk;//硬盘
    private InterCpu cpu;// cpu
    private KingstonMemory memory;//内存

    public Computer() {}

    public Computer(XiJieHardDisk hardDisk, InterCpu cpu, KingstonMemory memory) {
        this.hardDisk = hardDisk;
        this.cpu = cpu;
        this.memory = memory;
    }

    public XiJieHardDisk getHardDisk() {return hardDisk;}

    public void setHardDisk(XiJieHardDisk hardDisk) {
        this.hardDisk = hardDisk;
    }

    public InterCpu getCpu() {return cpu;}

    public void setCpu(InterCpu cpu) {this.cpu = cpu;}

    public KingstonMemory getMemory() {return memory;}

    public void setMemory(KingstonMemory memory) {
        this.memory = memory;
    }

    public void runComputer(){
        System.out.println("计算机正在工作...");
        cpu.runCpu();
        memory.saveMemory();
        hardDisk.saveDisk("你好Java。");
        String data = hardDisk.getData();
        System.out.println(data);
    }
}
=========================================================
  //测试类
  public class ComputerTest {
    public static void main(String[] args) {

        // 创建计算机组件内存、硬盘、cpu
        KingstonMemory k = new KingstonMemory();//表示内存
        InterCpu  i = new InterCpu();// 表示 cpu
        XiJieHardDisk x = new XiJieHardDisk();// 表示硬盘

        // 创建计算机对象,并组装(即,传入组件参数)
        Computer computer = new Computer(x,i,k);
        // 运行计算机
        computer.runComputer();
    }
}

上面代码可以看到已经组装了一台电脑,但是似乎组装的电脑的cpu只能是Intel的,内存条只能是金士顿的,硬盘只能是希捷的,这对用户肯定是不友好的,用户有了机箱肯定是想按照自己的喜好,选择自己喜欢的配件。如果想换成不是Intel的cpu需要修改Computer类,这就违背了开闭原则。

根据依赖倒转原则进行改进:

在这里插入图片描述

// Cpu接口
public interface Cpu {
    public abstract void runCpu();
}
===========================================================
  // 硬盘接口
public interface HardDisk {
    public abstract void saveDate(String date);

    public abstract String getDate();
}
==========================================================
  // 内存接口
public interface Memory {
    public abstract void saveMemory();
}
==========================================================
  //IntelCpu类实现Cpu接口
  public class IntelCpu implements Cpu{
    @Override
    public void runCpu() {
        System.out.println("InterCpu正在运行...");
    }
}
==========================================================
  // 新增Amd类型的cpu 
public class AmdCpu implements Cpu{
    @Override
    public void runCpu() {
        System.out.println("AMD Cpu正在运行...");
    }
}
==========================================================
  // KingstonMemory类实现Memory接口
public class KingstonMemory implements Memory{
    @Override
    public void saveMemory() {
        System.out.println("使用金士顿作为内存条...");
    }
}
==========================================================
  // XiJieHardDisk类实现HardDisk接口
public class XiJieHardDisk implements HardDisk{
    @Override
    public void saveDate(String date) {
        System.out.println("从硬盘获取的数据是:"+date);
    }

    @Override
    public String getDate() {
        System.out.println("获取硬盘数据操作...");
        return "获取硬盘数据完成。";
    }
}
============================================================
  //聚合各种组件
  public class Computer {
    private HardDisk hardDisk;
    private Cpu cpu;
    private Memory memory;

    public Computer() {}

    public Computer(HardDisk hardDisk, Cpu cpu, Memory memory) {
        this.hardDisk = hardDisk;
        this.cpu = cpu;
        this.memory = memory;
    }

    public HardDisk getHardDisk() {return hardDisk;}

    public void setHardDisk(HardDisk hardDisk) {
        this.hardDisk = hardDisk;
    }

    public Cpu getCpu() { return cpu;}

    public void setCpu(Cpu cpu) { this.cpu = cpu;}

    public Memory getMemory() { return memory;}

    public void setMemory(Memory memory) {
        this.memory = memory;
    }
    //运行计算机方法
    public void runComputer(){
        System.out.println("计算机正在工作...");
        cpu.runCpu();
        memory.saveMemory();
        hardDisk.saveDate("你好Java。");
        String data = hardDisk.getDate();
        System.out.println(data);
    }
}
=======================================================
  //测试类
  public class ComputerTest {
    public static void main(String[] args) {

        // 创建计算机的组件:内存、cpu、硬盘
        // Cpu cpu = new IntelCpu();
        Cpu cpu = new AmdCpu();
        HardDisk hardDisk = new XiJieHardDisk();
        Memory memory = new KingstonMemory();

      // 创建计算机
     Computer computer = new Computer(hardDisk,cpu,memory);

      // 运行计算机
      computer.runComputer();
    }
}

上述代码根据依赖倒转原则改进后扩展性比较好,如想换AMD类型的Cpu,只需子新增一个AmdCpu类去实现Cpu接口,重写Cpu里的抽象方法,再在测试类中去用Cpu接口去接AmdCpu的对象即可,这样就不用修改Computer类里面的代码了。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

演示:基于WPF的自绘的中国地铁轨道控件

一、目的:演示一个基于WPF的自绘的中国地铁轨道控件 二、效果演示 北京地铁 成都地铁 上海地铁 深圳地铁 南京地铁 长春地铁 哈尔滨地铁 武汉地铁 厦门地铁 香港地铁 三、功能 支持平移、缩放等操作 鼠标悬停显示线路信息和站点信息 按表格显示,按纸张…

MySQL —— 索引

索引的概念 MySQL的索引是⼀种数据结构,它可以帮助数据库高效地查询、更新数据表中的数据。索引通过 ⼀定的规则排列数据表中的记录,使得对表的查询可以通过对索引的搜索来加快速度。 MySQL索引类似于书籍的目录,通过指向数据行的位置&…

PCIe进阶之TL:First/Last DW Byte Enables Rules Traffic Class Field

1 First/Last DW Byte Enables Rules & Attributes Field 1.1 First/Last DW Byte Enables Rules Byte Enable 包含在 Memory、I/O 和 Configuration Request 中。本文定义了相应的规则。Byte Enable 位于 header 的 byte 7 。对于 TH 字段值为 1 的 Memory Read Request…

Requests-HTML模块怎样安装和使用?

要安装和使用Requests-HTML模块,您可以按照以下步骤进行操作: 打开命令行界面(如Windows的命令提示符或Mac的终端)。 使用pip命令安装Requests-HTML模块。在命令行中输入以下命令并按回车键执行: pip install request…

前端网页代码编辑器 Monaco Editor

前端网页代码编辑器 Monaco Editor Monaco Editor Monaco Editor 是由 Microsoft 开发的一款基于 Web 技术的开源代码编辑器,它是 Visual Studio Code 编辑器的核心。Monaco Editor 可以嵌入到网页中,提供类似于 Visual Studio Code 的编辑体验。 官方…

数据结构 Java DS——分享部分链表题目 (2)

目录 前言 题目一 —— 链表的回文结构 题目二 —— 二进制链表转整数 题目三 —— 设计链表 结尾 前言 关于JAVA的链表,笔者已经写了两篇博客来介绍了,今天给笔者们带来第三篇,也是分享了一些笔者写过的,觉得挺好的题目,链接也已经挂上了,笔者们可以去看看…

redis 基本数据类型—string类型

一、介绍 Redis 中的字符串,直接就是按照二进制数据的方式存储的,不会做任何的编码转换。 Redis对于 string 类型,限制了大小最大是512M 二、命令 SET 将 string 类型的 value 设置到 key 中。如果 key 之前存在,则覆盖&#…

亚马逊、沃尔玛、敦煌网、Target塔吉特、Temu环境搭建测评技术!

海外跨境电商各大主要平台正不断力推半托管模式,不断对商家开出众多吸引和扶持政策。全托管是指电商平台全面负责店铺的运营,包括仓储、配送、售后等,而商家主要负责提供货品。半托管模式则基本由商家自主经营,平台只负责仓配物流…

java中Class文件的文件格式

无关性的基石 计算机底层只能识别二进制,由CPU直接处理二进制,在底层上面是操作系统,在操作系统上面就是虚拟机,java有一个口号,“一次编写,到处运行”这个不太可能在操作系统层面上实现,不同的…

俄罗斯方块——C语言实践(Dev-Cpp)

目录 1、创建项目(尽量不使用中文路径) 2、项目复制 3、项目配置 ​1、调整编译器 2、在配置窗口选择参数标签 3、添加头文件路径和库文件路径 4、代码实现 4.1、main.c 4.2、draw.h 4.3、draw.c 4.4、shape.h 4.5、shape.c 4.6、board.h 4.7、board.c 4.8、cont…

Vue.js入门系列(二十九):深入理解编程式路由导航、路由组件缓存与路由守卫

个人名片 🎓作者简介:java领域优质创作者 🌐个人主页:码农阿豪 📞工作室:新空间代码工作室(提供各种软件服务) 💌个人邮箱:[2435024119qq.com] &#x1f4f1…

解锁编程潜力,从掌握GitHub开始

目录: 一、搜索开源项目 1、什么是Git 2、Github常用词含义 3、一个完整的项目界面 4、使用Github搜索项目 1)in关键词 2)star或fork数量去查找 3)awesome加强搜索 二、访问速度慢的解决 1、使用网易UU加速器 2、使用…

Visual Studio(vs)下载安装C/C++运行环境配置和基本使用注意事项

基本安装 点击跳转到vs官网点击箭头所指的按钮进行下载双击运行刚才下载好的下载器点击继续勾选“使用C的桌面开发”和“Visual Studio扩展开发”点击“安装位置”,对vs的安装位置进行更改。你可以跟我一样只选择D盘或者其他你空闲的盘,然后将默认的路径…

响应式CSS 媒体查询——WEB开发系列39

CSS媒体查询(Media Queries)是响应式设计中的核心技术之一,帮助我们在不同设备上展示不同的样式。通过媒体查询,开发者可以检测用户设备的特性,如屏幕宽度、高度、分辨率、方向等,针对性地调整网页布局。 一…

架构师知识梳理(七):软件工程-工程管理与开发模型

软件工程概述 软件开发生命周期 软件定义时期:包括可行性研究和详细需求分析过程,任务是确定软件开发工程必须完成的总目标,具体可分成问题定义、可行性研究、需求分析等。软件开发时期:就是软件的设计与实现,可分成…

气压测试实验(用IIC)

I2C: 如果没有I2c这类总线,连接方法可能会如下图: 单片机所有的通讯协议,无非是建立在引脚(高低电平的变换高低电平持续的时间)这二者的组合上,i2c 多了一个clock线,负责为数据传输打节拍。 (i2…

如何删除git提交记录

今天在提交github时,不小心提交了敏感信息, 不要问我提交了啥,问就是不知道 查了下资料,终于找到简单粗暴的方式来删除提交记录。方法如下 git reset --soft HEAD~i i代表要恢复到多少次提交前的状态,如指定i 2&…

一文读懂:如何将广告融入大型语言模型(LLM)输出

本文是我翻译过来的,讨论了在线广告行业的现状以及如何将大型语言模型(LLM)应用于在线广告。 原文请参见”阅读原文“。 在2024年,预计全球媒体广告支出的69%将流向数字广告市场。这个数字预计到2029年将增长到79%。在Meta的2024…

微服务——网关路由(Spring Cloud Gateway)

网关路由 1.什么是网关 网关又称网间连接器、协议转换器,是在网络层以上实现网络互连的复杂设备,主要用于两个高层协议不同的网络之间的互连。网关就是网络的关口。数据在网络间传输,从一个网络传输到另一网络时就需要经过网关来做数据的路由…

Kafka 基础与架构理解

目录 前言 Kafka 基础概念 消息队列简介:Kafka 与传统消息队列(如 RabbitMQ、ActiveMQ)的对比 Kafka 的组件 Kafka 的工作原理:消息的生产、分发、消费流程 Kafka 系统架构 Kafka 的分布式架构设计 Leader-Follower 机制与…