文章目录
-
- [3.3 依赖倒转原则(DIP)](#3.3 依赖倒转原则(DIP))
-
- 3.3.1概述
- [3.3.2 案例](#3.3.2 案例)
3.3 依赖倒转原则(DIP)
依赖倒转原则:Dependency Inversion Principle,DIP
3.3.1概述
高层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象。简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合。
3.3.2 案例
下面看一个例子来理解依赖倒转原则
【例】组装电脑
现要组装一台电脑,需要配件cpu,硬盘,内存条。只有这些配置都有了,计算机才能正常的运行。选择cpu有很多选择,如Intel,AMD等,硬盘可以选择希捷,西数等,内存条可以选择金士顿,海盗船等。
java
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类,这就违背了开闭原则。
根据依赖倒转原则进行改进:
java
// 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类里面的代码了。