【软件架构】【设计原则】依赖倒置

 一、什么是依赖倒置原则

Dependence Inversion Principle,简称DIP,是指高层模块(直接调用层)不应该依赖底层模块(具体的实现层),反过来也是,它们之间应该依赖抽象层。

也就是说在高层模块与底层模块之间,使用抽象层做桥梁,高层模块只管使用抽象层的东西,底层模块只管基于抽象层拓展各种个性功能,高层模块依赖抽象,底层模块依赖抽象,在运行态中传入不同的实例即可无缝地完成各种需求(借助了里氏替换原则),同时也是开闭原则的基础。

在java中具体点就是,在一个调用类(高层模块)中只调用接口/抽象类(抽象层)的方法,而使用各种不同的具体类(底层模块)去实现这个接口/抽象类的方法,在使用的时候直接传入这些具体类的实例可以达到调用不同的方法。

二、依赖倒置的优点

  • 强调面向接口编程,降低类与类之间的耦合性

使用接口或抽象类去定义规范和契约,不涉及具体操作,调用类直接遵循这些规范或契约来使用,不必担心具体是如何操作的;而实现类只管根据这些规范和契约去实现不同的功能,最终通过里氏替换,达到最终目的,相互独立、解耦,除非变动规范和契约

  • 增强系统的稳定性

具体细节变化多端,而抽象想多稳定,以抽象为基础、面向接口编程的系统比面向细节的稳定多了。

  • 提高代码的可读性和维护性

依赖关系清晰明了,高层与底层相互解耦,各自维护也相互不影响

  • 降低修改代码带来的风险

因为相互解耦,有一块功能代码出现bug,修改这一块代码不会影响其他块的正常使用。

三、依赖倒置的缺点

除了抽象难度大点以外,几乎0缺点,依赖倒置还是挺基础、使用的一个原则。

四、依赖倒置的具体实现

1.  定义一个接口(作为高层与底层的依赖桥梁)

public interface IBridge {
    void connect();
}

2. 定义一个调用类(高层模块,只依赖接口)

public class dock {
    public static void joint(IBridge bridge){
        bridge.connect();
    }
}

3. 定义多个接口的具体类(底层模块,只实现接口)

public class BridgeA implements IBridge {
    @Override
    public void connect() {
        System.out.println("连接船A");
    }
}

public class BridgeB implements IBridge {
    @Override
    public void connect() {
        System.out.println("连接船B");
    }
}

4. 测试类(只需要传入接口的实例即可完成调用)

public class Test {
    public static void main(String[] args) {
        Dock.joint(new BridgeA());
        Dock.joint(new BridgeB());
    }
}
输出:
           连接船A
           连接船B


(完)