14
07

设计模式五大原则(3):依赖倒置原则

依赖倒置原则给多人并行开发带来了极大的便利,可以同时开工,互不影响,不用等待细节模块的完工再开发业务模块。参与协作开发的人越多、项目越庞大,采用依赖导致原则的意义就越重大。


赖倒置原则(Dependence Inversion Principle  DIP):依赖于抽象,而不依赖于具体。不对实现进行编程,这样就降低了客户与实现模块间的耦合

定义:

1.高层模块不应该依赖低层模块,两者都应该依赖其抽象

2.抽象不应该依赖细节

3.细节应该依赖抽象

 

问题由来:类A直接依赖类B,假如要将类A改为依赖类C,则必须通过修改类A的代码来达成。修改类A则可能会给程序带来不必要的风险。

解决方案:将类A修改为依赖接口I,类B和类C各自实现接口I,类A通过接口I间接与类B或者类C发生联系,则会大大降低修改类A的几率

举例说明:打印机功能的实现必须依赖于墨盒的功能实现,因此我们设计了如下结构

1

代码如下:

打印机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独立于它所控制的具体细节,而是依赖抽象。这就是面向对象中的“依赖倒置”机制。重构:

2

代码如下:

接口  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方法中无论是喷墨还是雕刻打印机本身都不会再关心了。

一个应用中的策略或业务的实现依赖于细节的实现,然而细节的实现或修改直接影响了应用策略或业务本身,这种情况是荒谬的。应该是策略或业务去迫使那些细节发生改变,无论如何策略不应该依赖于细节。、只有高层模块独立于低层模块时,复用才有可能。

依赖倒置原则给多人并行开发带来了极大的便利,可以同时开工,互不影响,不用等待细节模块的完工再开发业务模块。参与协作开发的人越多、项目越庞大,采用依赖导致原则的意义就越重大。

依赖倒置原则的核心就是要我们面向接口编程,理解了面向接口编程,也就理解了依赖倒置。

 


蜗牛学院,只为成就更好的你!

你!敢不敢!用你三个月的时间,换你不一样的未来!

赶快关注蜗牛学院官方微信,了解更多信息吧!

20181009_153045_341.jpg



版权所有,转载本站文章请注明出处:蜗牛学苑, https://www.woniuxy.cn/article/15