依赖倒转原则
高层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象。
简单地说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合。
🌰举个栗子
我们要组装一台电脑,需要配cpu、硬盘、内存条。但这些配件分别有很多选择,我们对此构建类图如下:
❌错误范例
假定我们的cpu使用Intel,硬盘使用希捷,内存条使用金士顿家的
所以我们分别创建三者的类,其中只需要写一个方法来输出各位的名字即可:
//Intel.class
public void run() {
System.out.println("俺是Intel处理器!");
}
//KingstonMemory.class
public void save() {
System.out.println("👴是金士顿");
}
//XiJieHardDisk.class
public void save() {
System.out.println("👴是希捷硬盘");
}
创建computer类:
//Computer.class
private IntelCpu cpu;
private XiJieHardDisk hardDisk;
private KinstonMemory memory;
//省略getter、setter
我们去测试类中将其组装好~~
//Test.class
IntelCpu cpu = new IntelCpu();
XiJieHardDisk hardDisk = new XiJieHardDisk();
KinstonMemory memory = new KingstonMemory();
Computer c = new Computer();
//组装计算机
c.setCpu(cpu);
c.setHardDisk(hardDisk);
c.setMemory(memory);
这样,我们就组装好了一台电脑。
但是,这样组装好的电脑,cpu只能用Intel,内存条只能用金士顿,硬盘只能用希捷,不能供用户自定义,这样就显得不友好咯,我们的目的是让用户可以自由选择自己喜欢的牌子,对电脑进行组装。
于是我们进行修改:
✔正确范例
我们利用依赖倒转原则进行改进:
我们将为各配件定义其抽象接口,让Computer类依赖抽象接口,而不是依赖于各个组件具体的实现类
对应类图:
有了接口当中间人,我们组装的Computer类就可以不用直接依赖特定的组件,而是依赖其抽象出来的接口:
//Computer.class
private HardDisk hardDisk;
private Cpu cpu;
private Memory memory;
这样在new一个新电脑的时候,就可以挑选自己喜欢的品牌传入,而不是像此前一样直接写死,大大增加了灵活性!这就是依赖倒转原则。