软件设计原则—依赖倒转原则

news/2024/11/17 5:23:07/文章来源:https://www.cnblogs.com/lm02/p/18200583

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

简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合。

image

下面看一个例子来理解依赖倒转原则:组装电脑

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

image

希捷硬盘类XiJieHardDisk)

package com.lmcode.principles.DependenceInversionPrinciple;// 希捷硬盘
public class XiJieHardDisk {public void save(String data) {System.out.println("使用希捷硬盘存储数据" + data);}public String get() {System.out.println("使用希捷希捷硬盘取数据");return "数据";}
}

Intel处理器IntelCpu

package com.lmcode.principles.DependenceInversionPrinciple;// Intel处理器
public class IntelCpu {public void run() {System.out.println("使用Intel处理器");}
}

金士顿内存条KingstonMemory

package com.lmcode.principles.DependenceInversionPrinciple;// 金士顿内存条
public class KingstonMemory {public void save() {System.out.println("使用金士顿作为内存条");}
}

电脑Computer

package com.lmcode.principles.DependenceInversionPrinciple;public class Computer {private XiJieHardDisk hardDisk;private IntelCpu cpu;private KingstonMemory memory;public IntelCpu getCpu() {return cpu;}public void setCpu(IntelCpu cpu) {this.cpu = cpu;}public KingstonMemory getMemory() {return memory;}public void setMemory(KingstonMemory memory) {this.memory = memory;}public XiJieHardDisk getHardDisk() {return hardDisk;}public void setHardDisk(XiJieHardDisk hardDisk) {this.hardDisk = hardDisk;}public void run() {System.out.println("计算机工作");cpu.run();memory.save();String data = hardDisk.get();System.out.println("从硬盘中获取的数据为:" + data);}
}

测试类main用来组装电脑。

package com.lmcode.principles.DependenceInversionPrinciple;public class main {public static void main(String[] args) {// 创建组件对象XiJieHardDisk xiJieHardDisk = new XiJieHardDisk();IntelCpu intelCpu = new IntelCpu();KingstonMemory kingstonMemory = new KingstonMemory();// 创建电脑对象Computer computer = new Computer();// 组装computer.setCpu(intelCpu);computer.setHardDisk(xiJieHardDisk);computer.setMemory(kingstonMemory);// 运行computer.run();}
}

上面代码可以看到已经组装了一台电脑,但是似乎组装的电脑的cpu只能是Intel的,内存条只能是金士顿的,硬盘只能是希捷的,这对用户肯定是不友好的,用户有了机箱肯定是想按照自己的喜好,选择自己喜欢的配件。

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

代码我们只需要修改Computer类,让Computer类依赖抽象(各个配件的接口),而不是依赖于各个组件具体的实现类。

image

面向对象的开发很好的解决了这个问题,一般情况下抽象的变化概率很小,让用户程序依赖于抽象,实现的细节也依赖于抽象。即使实现

细节不断变动,只要抽象不变,客户程序就不需要变化。这大大降低了客户程序与实现细节的耦合度。

cpu接口,硬盘接口,内存条接口

package com.lmcode.principles.DependenceInversionPrinciplePro;//cpu接口
public interface Cpu {
//    运行cpupublic void run();
}
package com.lmcode.principles.DependenceInversionPrinciplePro;// 硬盘接口
public interface HardDisk {
//    存储数据public void save(String data);
//    获取数据public String get();
}
package com.lmcode.principles.DependenceInversionPrinciplePro;//内存条接口
public interface Memory {public void save();
}

实现类

package com.lmcode.principles.DependenceInversionPrinciplePro;// Intel处理器
public class IntelCpu implements Cpu{public void run() {System.out.println("使用Intel处理器");}
}
package com.lmcode.principles.DependenceInversionPrinciplePro;// 金士顿内存条
public class KingstonMemory implements Memory{public void save() {System.out.println("使用金士顿作为内存条");}
}
package com.lmcode.principles.DependenceInversionPrinciplePro;// 希捷硬盘
public class XiJieHardDisk implements HardDisk{public void save(String data) {System.out.println("使用希捷硬盘存储数据" + data);}public String get() {System.out.println("使用希捷硬盘取数据");return "数据";}
}

Computer

此时声明组件不能声明具体的实现类,而是父接口类型的抽象

package com.lmcode.principles.DependenceInversionPrinciplePro;public class Computer {//    声明组件不能声明具体的实现类,而是父接口类型的抽象private HardDisk hardDisk;private Cpu cpu;private 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 run() {System.out.println("计算机工作");cpu.run();memory.save();String data = hardDisk.get();System.out.println("从硬盘中获取的数据为:" + data);}
}

main

package com.lmcode.principles.DependenceInversionPrinciplePro;public class main {public static void main(String[] args) {// 创建组件对象HardDisk hardDisk = new XiJieHardDisk();Cpu cpu = new IntelCpu();Memory memory = new KingstonMemory();// 创建电脑对象Computer computer = new Computer();// 组装computer.setCpu(cpu);computer.setHardDisk(hardDisk);computer.setMemory(memory);// 运行computer.run();}
}

此时加入需要换cpu,只需要创建一个cpu的类,实现cpu接口,然后再main中创建新的cpu然后作为参数传递

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

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

相关文章

关于没有熔断降级导致服务重启问题

场景 1.k8s微服务触发重启 容器配置的健康检查采用actuator curl 127.0.0.1:8080/actuator/health 2.容器重启钩子回调curl -X POST http://127.0.0.1:8080/actuator/shutdown 最终原因是因为调用第三方服务,超时设置3秒,重试3次,三方服务挂起导致tomcat连接池占满,健康检查…

stm32 bootloader的app中断向量偏移设置,HAL库

如何设置Hal库的中断向量偏移看前几篇的 stm32f103c8t6 HAL库更改中断向量表(app部分) - 这一切足够了 - 博客园 (cnblogs.com)我这里bootloader的APP开始地址就是0x08006000,中断向量偏移0x00006000 设置完成之后编译mdk,将生成的bin文件使用ymodem写入0x08006000中 这里设…

c语言程序实验————实验报告九

c语言程序实验————实验报告九实验项目名称: 实验报告8 字符串处理函数 实验项目类型:验证性 实验日期:2024 年 5 月 16 日一、实验目的 1.掌握定义函数的方法 2.掌握函数调用、实参与形参的对应关系、参数的传递方式 3.掌握函数的嵌套调用和递归调用的方法 4.掌握全局变…

Flink精确消费一次

在大数据计算里面,计算引擎是处于承上启下的作用,对上承接数据源,对下承接各种各种数据库,比如mysql、oracle。对于任何数据计算来说要想精确消费一次,就需要支持事务或者幂等,我们最常见的支持事务的就是单点的oracle、mysql数据库,那么Flink作为分布式计算引擎,是如何…

电子传输系统安全-进展1

实验二 电子传输系统安全-进展1 上周任务完成情况完成了上学期电子公文传输系统的重新调试通过 部署了bouncycastle 学习了bouncycastle 将jar包添加到依赖项本周计划将上学期电子公文传输系统重新调试通过 部署bouncycastle 学习bouncycastle 将jar包添加到依赖项参考链接Boun…

【日记】被零食有鸣的工作人员轰出来了……(544 字)

正文今天全在睡觉。早上睡到十点起床,下午又从三点睡到五点,我愿称之为睡觉仙人…… 这就是上班的副作用吗……下午同事一个电话打过来,决定不接。周末同事来电话,准没好事。结果她微信发消息问,要不要出去走走,一个人有点闷。我都惊了,头一回。我还以为又要我做啥事儿呢…

d3d12龙书阅读----绘制几何体(上) 课后习题

d3d12龙书阅读----绘制几何体(上) 课后习题 练习1 完成相应的顶点结构体的输入-布局对象typedef struct D3D12_INPUT_ELEMENT_DESC{一个特定字符串将顶点结构体数组里面的顶点映射到顶点着色器的输入签名LPCSTR SemanticName;语义索引 如果语义名相同的话 使用索引进行区分UI…

SAP PS 打开关闭的项目

1 ) 编辑-状态-关闭-撤销 2) TECO 撤销: ) 编辑-状态-技术完成-撤销

stm32f103c8t6使用bootloader进行ymodem下载和app程序测试,部分总结(暂未测试中断向量偏移问题)

bootloader程序部分(功能测试)print_boot_message();/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */uint8_t key_get_state;while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */key_get_state = get_key();switch(key_get_state){case 1: //…

夸克自动签到转存到emby

夸克自动签到不同于之前的阿里盘内夸克签到脚本,这里可以自动转存管理文件,添加到emby中 b站视频地址:https://www.bilibili.com/video/BV1ry411a7Lt 一、准备 你有服务器或者nas等等,有docker或者青龙都行。 由于nas在家关机了,我在外地。就不演示推到emby了。 来自于Cp0…

AI绘画拉取模型失败,DOS开启代理

我用了这么久的代理第一次知道DOS里面要开代理,惭愧惭愧。在我远程拉取模型的时候,挂科学也一直失败。在网上找报错找了很长时间没找到,最后经过一位群友的提示下,才知道问题出在DOS代理上面。直接看文章第一部分就行,要是直接tun不行,再看下面的直接开启tun这个是V2的开…

e语言 文本换行问题

我帮这人重写了下本文来自博客园,作者:__username,转载请注明原文链接:https://www.cnblogs.com/code3/p/18200506