深浅模式
依赖倒转原则
高层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象。简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合。 下面看一个例子来理解依赖倒转原则 【例】组装电脑 现要组装一台电脑,需要配件cpu,硬盘,内存条。只有这些配置都有了,计算机才能正常的运行。选择cpu有很多选择,如Intel,AMD等,硬盘可以选择希捷,西数等,内存条可以选择金士顿,海盗船等。
类图如下
代码如下: 希捷硬盘类(XiJieHardDisk):
java
package com.notecove.designpractice.yldz.before;
/**
* 希捷硬盘
*/
public class XiJieHardDisk {
public void save(String data){
System.out.println("使用希捷硬盘存储数据为 希捷硬盘");
}
public String get(){
System.out.println("使用希捷硬盘读取数据");
return "数据";
}
}Intel处理器(IntelCpu):
java
package com.notecove.designpractice.yldz.before;
/**
* intel cpu
*/
public class IntelCpu {
public void run(){
System.out.println("使用Intel处理器");
}
}金士顿内存条(KingstonMemory):
java
package com.notecove.designpractice.yldz.before;
public class KingstonMemory {
public void save() {
System.out.println("使用金士顿作为内存条");
}
}电脑(Computer):
java
package com.notecove.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):
java
package com.notecove.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):
java
package com.notecove.designpractice.yldz.after;
import com.notecove.designpractice.yldz.before.KingstonMemory;
import com.notecove.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);
}
}面向对象的开发很好的解决了这个问题,一般情况下抽象的变化概率很小,让用户程序依赖于抽象,实现的细节也依赖于抽象。即使实现细节不断变动,只要抽象不变,客户程序就不需要变化。这大大降低了客户程序与实现细节的耦合度。
