Java七大设计原则(4/7)——依赖倒转原则

132 阅读2分钟

本文已参加「新人创作礼」活动,一起开启掘金创作之路。

定义

上层模块不应该依赖底层模块,它们都应该依赖于抽象,抽象不应该依赖于细节,细节应该依赖于抽象。

简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合。


代码实现

假设现在要叫朋友John上号,选择通过微信发消息。

不使用依赖倒转原则

定义微信类,用来发消息

/**
 * @author John117
 * @date 2022/05/23  17:30
 */
public class WeChat {
    public void sendMessage(){
        System.out.println("微信:速度上号");
    }
}

定义John类,用来接受消息

/**
 * @author John117
 * @date 2022/05/23  17:32
 */
public class John {
    public void getMessage(WeChat weChat){
        weChat.sendMessage();
    }
}

测试

/**
 * @author John117
 * @date 2022/05/23  17:35
 */
public class Test {
    public static void main(String[] args) {
        new John().getMessage(new WeChat());
    }
}

这种设计有个很大的缺点,假如此时想再添加一个通讯方式比如钉钉,在定义钉钉类后,还要去修改John的接受方式。在现实工程中,这种做法工程量太大了。

使用依赖倒转原则

面向接口,定义一个消息类接口IMessage

/**
 * @author John117
 * @date 2022/05/23  17:35
 */
public class Test {
    public static void main(String[] args) {
        new John().getMessage(new WeChat());
    }
}

定义WeChat类,WeChat实现IMessage

/**
 * @author John117
 * @date 2022/05/23  17:37
 */
public class WeChat implements IMessage{
    @Override
    public void sendMessage() {
        System.out.println("微信:速度上号");
    }
}

定义John

/**
 * @author John117
 * @date 2022/05/23  17:37
 */
public class John {
    public void getMessage(IMessage message){
        message.sendMessage();
    }
}

测试

/**
 * @author John117
 * @date 2022/05/23  17:39
 */
public class Test {
    public static void main(String[] args) {
        new John().getMessage(new WeChat());
    }
}

此时,如果想在添加一个通讯方式钉钉,只需定义DingDing类,使DingDing实现IMessage

/**
 * @author John117
 * @date 2022/05/23  17:39
 */
public class DingDing implements IMessage{
    @Override
    public void sendMessage() {
        System.out.println("钉钉:速度上号");
    }
}

在测试类,传入相应消息实体类即可

public class Test {
    public static void main(String[] args) {
        new John().getMessage(new WeChat());
        new John().getMessage(new DingDing());
    }
}

结论

  1. 低层模块尽量都要有抽象类或接口,或者两者都有,

  2. 程序稳定性更好,变量的声明类型尽量是抽象类或者接口,这样我们的变量引用和实际对象间,就存在一个缓冲层, 利于程序扩展和优化