设计模式-软件设计原则-依赖倒转原则
高层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象。简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合。
下面看一个例子来理解依赖倒转原则
【例】组装电脑
现要组装一台电脑,需要配件cpu,硬盘,内存条。只有这些配置都有了,计算机才能正常的运行。选择cpu有很多选择,如Intel,AMD等,硬盘可以选择希捷,西数等,内存条可以选择金士顿,海盗船等。
类图如下:
代码如下:
希捷硬盘类(XiJieHardDisk):
package com.mangoubiubiu.designpractice.yldz.before; /** * 希捷硬盘 */ public class XiJieHardDisk { public void save(String data){ System.out.println("使用希捷硬盘存储数据为 希捷硬盘"); } public String get(){ System.out.println("使用希捷硬盘读取数据"); return "数据"; } }
Intel处理器(IntelCpu):
package com.mangoubiubiu.designpractice.yldz.before; /** * intel cpu */ public class IntelCpu { public void run(){ System.out.println("使用Intel处理器"); } }
金士顿内存条(KingstonMemory):
package com.mangoubiubiu.designpractice.yldz.before; public class KingstonMemory { public void save() { System.out.println("使用金士顿作为内存条"); } }
电脑(Computer):
package com.mangoubiubiu.designpractice.yldz.before; /** * 电脑 */ public class Computer { private KingstonMemory kingstonMemory; private IntelCpu intelCpu; private XiJieHardDisk xiJieHardDisk; public KingstonMemory getKingstonMemory() { return kingstonMemory; } public void setKingstonMemory(KingstonMemory kingstonMemory) { this.kingstonMemory = kingstonMemory; } public IntelCpu getIntelCpu() { return intelCpu; } public void setIntelCpu(IntelCpu intelCpu) { this.intelCpu = intelCpu; } public XiJieHardDisk getXiJieHardDisk() { return xiJieHardDisk; } public void setXiJieHardDisk(XiJieHardDisk xiJieHardDisk) { this.xiJieHardDisk = xiJieHardDisk; } public void run(){ System.out.println("计算机工作"); intelCpu.run(); kingstonMemory.save(); String data = xiJieHardDisk.get(); System.out.println("从硬盘中获取的数据为:" + data); } }
测试类(TestComputer):
package com.mangoubiubiu.designpractice.yldz.before; public class TestComputer { public static void main(String[] args) { Computer computer=new Computer(); computer.setIntelCpu(new IntelCpu()); computer.setKingstonMemory(new KingstonMemory()); computer.setXiJieHardDisk(new XiJieHardDisk()); computer.run(); } }
上面代码可以看到已经组装了一台电脑,但是似乎组装的电脑的cpu只能是Intel的,内存条只能是金士顿的,硬盘只能是希捷的,这对用户肯定是不友好的,用户有了机箱肯定是想按照自己的喜好,选择自己喜欢的配件。
根据依赖倒转原则进行改进:
代码我们只需要修改Computer类,让Computer类依赖抽象(各个配件的接口),而不是依赖于各个组件具体的实现类。
类图如下:
电脑(Computer):
package com.mangoubiubiu.designpractice.yldz.after; import com.mangoubiubiu.designpractice.yldz.before.KingstonMemory; import com.mangoubiubiu.designpractice.yldz.before.XiJieHardDisk; /** * 电脑 */ public class Computer { private Cpu cpu; private HardDisk hardDisk; private Memory memory; public Cpu getCpu() { return cpu; } public void setCpu(Cpu cpu) { this.cpu = cpu; } public HardDisk getHardDisk() { return hardDisk; } public void setHardDisk(HardDisk hardDisk) { this.hardDisk = hardDisk; } 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); } }
面向对象的开发很好的解决了这个问题,一般情况下抽象的变化概率很小,让用户程序依赖于抽象,实现的细节也依赖于抽象。即使实现细节不断变动,只要抽象不变,客户程序就不需要变化。这大大降低了客户程序与实现细节的耦合度。
本文作者:KwFruit
本文链接:https://www.cnblogs.com/mangoubiubiu/p/15952869.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步