什么是依赖倒转原则
依赖倒转(Dependence Inversion Principle ):是程序要依赖于抽象接口,不要依赖于具体实现。简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就下降了客户与实现模块间的耦合。html
1.抽象不该该依赖于细节,细节应该依赖于抽象。编程
2.高层模块不依赖底层模块,二者都依赖抽象。 框架
咱们举个例子:电脑有不一样的组件,硬盘,内存,主板。this
硬盘抽象类url
1 //硬盘抽象类 2 public abstract class HardDisk { 3 public abstract void doSomething(); 4 }
具体硬盘(希捷硬盘)spa
1 //希捷硬盘 2 public class XiJieHardDisk extends HardDisk { 3 4 public void doSomething() { 5 System.out.println("希捷硬盘"); 6 } 7 8 }
具体硬盘(西数硬盘).net
1 public class XiShuHardDisk extends HardDisk { 2 3 public void doSomething() { 4 System.out.println("西数硬盘"); 5 } 6 7 }
主板抽象类 设计
1 //主板抽象类 2 public abstract class MainBoard { 3 public abstract void doSomething(); 4 }
具体主板(华硕主板)3d
1 public class HuaShuoMainBoard extends MainBoard{ 2 3 public void doSomething() { 4 System.out.println("华硕主板"); 5 } 6 7 }
具体主板(微星主板)code
1 public class WeiXingMainBoard extends MainBoard { 2 3 public void doSomething() { 4 System.out.println("微星主板"); 5 } 6 7 }
内存抽象类
1 //内存抽象类 2 public abstract class Memory { 3 public abstract void doSomething(); 4 }
具体内存(金士顿内存)
1 public class JinShiDunMemory extends Memory { 2 3 public void doSomething() { 4 System.out.println("金士顿内存"); 5 } 6 7 }
具体内存(三星内存)
1 public class SanxingMemory extends Memory { 2 3 public void doSomething() { 4 System.out.println("三星内存"); 5 } 6 7 }
如今,电脑的各个零部件都有了,只差电脑了。首先,咱们不按照依赖倒转原则,按照传统模式
传统的过程式设计倾向于使高层次的模块依赖于低层次的模块,抽象层依赖于具体的层次。
这样,电脑应该是这样的
1 //电脑 2 public class Computer{ 3 private HuaShuoMainBoard huaShuoMainBoard; 4 private JinShiDunMemory jinShiDunMemory; 5 private XiJieHardDisk xiJieHardDisk; 6 7 public HuaShuoMainBoard getHuaShuoMainBoard() { 8 return huaShuoMainBoard; 9 } 10 public void setHuaShuoMainBoard(HuaShuoMainBoard huaShuoMainBoard) { 11 this.huaShuoMainBoard = huaShuoMainBoard; 12 } 13 public JinShiDunMemory getJinShiDunMemory() { 14 return jinShiDunMemory; 15 } 16 public void setJinShiDunMemory(JinShiDunMemory jinShiDunMemory) { 17 this.jinShiDunMemory = jinShiDunMemory; 18 } 19 public XiJieHardDisk getXiJieHardDisk() { 20 return xiJieHardDisk; 21 } 22 public void setXiJieHardDisk(XiJieHardDisk xiJieHardDisk) { 23 this.xiJieHardDisk = xiJieHardDisk; 24 } 25 }
这时,要组装一台电脑
public class MainClass { public static void main(String[] args) { Computer computer = new Computer(); computer.setHuaShuoMainBoard(new HuaSuoMainBoard()); computer.setJinShiDunMemory(new JinShiDunMemory()); computer.setXiJieHardDisk(new XiJieHardDisk()); computer.setHuaShuoMainBoard(new WeiXingMainBoard());//报错,没法安装 } }
能够看到,这种状况下,这台电脑就只能安装华硕主板,金士顿内存和希捷硬盘了,这对用户确定是不友好的,用户有了机箱确定是想按照本身的喜爱,选择本身喜欢的配件。
电脑就是高层业务逻辑,主板,内存,硬盘就是中层模块,还有更低的底层模块咱们没有写那么细,但都是一个意思,这样的方式显然是不可取的。
下面,咱们改造一下,让Computer依赖接口或抽象类,下面的模块一样如此
Computer
1 public class Computer { 2 private MainBoard mainBoard; 3 private Memory memory; 4 private HardDisk harddisk; 5 6 public MainBoard getMainBoard() { 7 return mainBoard; 8 } 9 10 public void setMainBoard(MainBoard mainBoard) { 11 this.mainBoard = mainBoard; 12 } 13 14 public Memory getMemory() { 15 return memory; 16 } 17 18 public void setMemory(Memory memory) { 19 this.memory = memory; 20 } 21 22 public HardDisk getHarddisk() { 23 return harddisk; 24 } 25 26 public void setHarddisk(HardDisk harddisk) { 27 this.harddisk = harddisk; 28 } 29 }
这时,再组装
1 public class MainClass { 2 public static void main(String[] args) { 3 Computer computer = new Computer(); 4 computer.setMainBoard(new HuaSuoMainBoard()); 5 computer.setMemory(new JinShiDunMemory()); 6 computer.setHarddisk(new XiJieHardDisk()); 7 8 computer.setMainBoard(new WeiXingMainBoard());//彻底没有问题 9 } 10 }
这样,用户就能够根据本身的喜爱来选择本身喜欢的品牌,组装电脑了。
为何要采起依赖倒转这种方式
面向过程的开发,上层调用下层,上层依赖于下层,当下层剧烈变更时上层也要跟着变更,这就会致使模块的复用性下降并且大大提升了开发的成本。
面向对象的开发很好的解决了这个问题,通常状况下抽象的变化几率很小,让用户程序依赖于抽象,实现的细节也依赖于抽象。即便实现细节不断变更,只要抽象不变,客户程序就不须要变化。这大大下降了客户程序与实现细节的耦合度。
依赖倒转模式应用实例
1.工厂方法模式
2.模板方法模式
3.迭代模式
综上所诉,咱们能够看出一个应用中的重要策略决定及业务模型正是在这些高层的模块中。也正是这些模型包含着应用的特性。可是,当这些模块依赖于低层模块时,低层模块的修改将会直接影响到它们,迫使它们也去改变。这种境况是荒谬的。应该是处于高层的模块去迫使那些低层的模块发生改
变。应该是处于高层的模块优先于低层的模块。不管如何高层的模块也不该依赖于低层的模块。并且,咱们想可以复用的是高层的模块。经过子程序库的形式,咱们已经能够很好地复用低层的模块了。当高层的模块依赖于低层的模块时,这些高层模块就很难在不一样的环境中复用。可是,当那些高层模块独
立于低层模块时,它们就能很简单地被复用了。这正是位于框架设计的最核心之处的原则。