设计模式五大原则(3):依赖倒置原则
依赖倒置原则给多人并行开发带来了极大的便利,可以同时开工,互不影响,不用等待细节模块的完工再开发业务模块。参与协作开发的人越多、项目越庞大,采用依赖导致原则的意义就越重大。
依赖倒置原则(Dependence Inversion Principle DIP):依赖于抽象,而不依赖于具体。不对实现进行编程,这样就降低了客户与实现模块间的耦合
定义:
1.高层模块不应该依赖低层模块,两者都应该依赖其抽象
2.抽象不应该依赖细节
3.细节应该依赖抽象
问题由来:类A直接依赖类B,假如要将类A改为依赖类C,则必须通过修改类A的代码来达成。修改类A则可能会给程序带来不必要的风险。
解决方案:将类A修改为依赖接口I,类B和类C各自实现接口I,类A通过接口I间接与类B或者类C发生联系,则会大大降低修改类A的几率
举例说明:打印机功能的实现必须依赖于墨盒的功能实现,因此我们设计了如下结构
代码如下:
打印机Printer :
public class Printer {
public static enum BoxType{Black,Color};
private BoxType type;
public void print(BoxType type){
if(type == BoxType.Black){
BlackCartridge bc = new BlackCartridge();
bc.inkjet();
}
if(type == BoxType.Color){ColorCartridge cc = new ColorCartridge();
cc.colorInkjet();
}
}
}
黑色墨盒 BlackCartridge:
public class BlackCartridge {
public void inkjet(){
System.out.println("黑色墨盒执行喷墨打印");
}
}
彩色墨盒 ColorCartridge:
public class ColorCartridge {
public void colorInkjet(){
System.out.println("彩色墨盒执行喷墨打印");
}
}
启动 Start:
public class Start {
public static void main(String[] args) {
new Printer().print(Printer.BoxType.Black);
}
}
结果:
黑色墨盒执行喷墨打印
彩色墨盒执行喷墨打印
目前代码完全满足我们的需求,但是现在我们将扩展新的打印机—激光打印机,那么我们必须修改打印机,打印机将依赖于激光头完成打印功能
代码如下:
public class Printer {
public static enum BoxType{Black,Color, laser};
private BoxType type;
public void print(BoxType type){
if(type == BoxType.Black){
BlackCartridge bc = new BlackCartridge();
bc.inkjet();
}
if(type == BoxType.Color){ColorCartridge cc = new ColorCartridge();
cc.colorInkjet();
}
if(type == BoxType.laser){
PUH puh = new PUH();
puh.writer();
}
}
}
即使是这样的修改也能满足我们的需求,但是业务在不断变化,需求在不断增加,如果我们在加入针式打印、硒鼓打印…..仅仅依靠修改Printer类来实现功能,不仅维护成本高,而且还会使Printer类代码僵硬脆弱,增加了出现异常的风险
导致上面所述问题一个原因是,含有高层策略的模块,依赖于它所控制的低层的具体细节的模块(打印机依赖于墨盒的实现)。我们必须得使Printer独立于它所控制的具体细节,而是依赖抽象。这就是面向对象中的“依赖倒置”机制。重构:
代码如下:
接口 Box:
public interface Box {
public abstract void doPrint();
}
黑色墨盒 BlackCartridge:
public class BlackCartridge {
public void doPrint (){
System.out.println("黑色墨盒执行喷墨打印");
}
}
彩色墨盒 ColorCartridge:
public class ColorCartridge implements Box{
public void doPrint (){
System.out.println("彩色墨盒执行喷墨打印");
}
}
打印机Printer :
public class Printer {
public void print(Box box){
box. doPrint ();
}
}
重构以后打印机依赖于Box这个抽象体,而与具体的实现细节墨盒或者针头无关,所以实现细节的变化不会影响打印机。至于实现的细节只要实现Box接口,在doPrint方法中无论是喷墨还是雕刻打印机本身都不会再关心了。
一个应用中的策略或业务的实现依赖于细节的实现,然而细节的实现或修改直接影响了应用策略或业务本身,这种情况是荒谬的。应该是策略或业务去迫使那些细节发生改变,无论如何策略不应该依赖于细节。、只有高层模块独立于低层模块时,复用才有可能。
依赖倒置原则给多人并行开发带来了极大的便利,可以同时开工,互不影响,不用等待细节模块的完工再开发业务模块。参与协作开发的人越多、项目越庞大,采用依赖导致原则的意义就越重大。
依赖倒置原则的核心就是要我们面向接口编程,理解了面向接口编程,也就理解了依赖倒置。
蜗牛学院,只为成就更好的你!
你!敢不敢!用你三个月的时间,换你不一样的未来!
赶快关注蜗牛学院官方微信,了解更多信息吧!