简单聊一聊什么是依赖倒置原则?

301 阅读2分钟

依赖倒置原则

依赖倒置原则(Dependency Inversion Principe,DIP)原始定义:

High level modules should not depend upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should depend upon abstractions.

翻译过来

  1. 高级模块不应依赖于低级模块,两者都应该依赖于抽象。
  2. 抽象不应依赖细节。
  3. 细节应该依靠抽象。

高层模块和低级模块容易理解,每一个逻辑的实现都是由原子逻辑组成的,不可分割的原子逻辑就是底层模块,原子逻辑在组装就是高级模块。

什么是抽象?什么是细节?

在Java语言中,抽象就是只接口或者抽象类,两者都是不能被直接被实例化的。细节就是实现类,实现接口或继承抽象类而产生的的类就是细节,其特点就是可以被实例化。

依赖倒置原则在Java语言中的表现:

  • 模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生的;
  • 接口或抽象类不依赖于实现类;
  • 实现类依赖接口或抽象。

更加精简的定义就是面向接口编程(OOD,Object-Oriented Design,面向对象设计)的精髓之一。

采用依赖倒置原则可以减少类间的耦合性,提高系统的稳定性,降低并行开发引起风险,提高代码可读性和可维护性。

example

public interface IDriver {
    
    public void drive(ICar car);
        
}

public class Driver implements IDriver {
    
    public void drive(ICar car) {
        car.run();
    }
    
}

public interface ICar {
    
    public void run();
        
}

public class Benz implements ICar {
    
    public void drive(ICar car) {
        System.out.println("Benz run ...");
    }
    
}

public class BWM implements ICar {
    
    public void drive(ICar car) {
        System.out.println("BWM run ...");
    }
    
}

/**
 * 业务1
 */
public class Client {
    
    public static void mian(String[] args) {
        IDriver zhangSan = new Driver();
        ICar benz = new Benz();
        zhangSan.drive(benz);
    }
    
}

/**
 * 业务2
 */
public class Client {
    
    public static void mian(String[] args) {
        IDriver zhangSan = new Driver();
        ICar bmw = new BMW();
        zhangSan.drive(bmw);
    }
    
}

依赖的三种写法

构造函数传递依赖对象

在类中通过构造函数声明依赖对象,按照依赖注入的说法,这种方法叫做构造函数注入。

public interface IDriver {
    
    public void drive();
        
}

public class Driver implements IDriver {
    
    private ICar car;
    
    public Driver(ICar car) {
        this.car = car;
    }
    
    public void drive() {
        this.car.run();
    }
    
}

Setter方法传递依赖对象

在抽象中设置Setter方法声明依赖关系,依照依赖注入的说法,这是Setter注入,按照这种方式注入。

public interface IDriver {
    
    public void drive();
    
    public void setCar(ICar car);
        
}

public class Driver implements IDriver {
    
    private ICar car;
    
    public viod setCar(ICar car) {
        this.car = car;
    }
    
    public void drive(ICar car) {
        this.car.run();
    }
    
}

接口声明依赖注入

在接口方法中声明依赖对象,也叫作接口注入。

public interface IDriver {
    
    public void drive(ICar car);
        
}

public class Driver implements IDriver {
    
    public void drive(ICar car) {
        car.run();
    }
    
}

public interface ICar {
    
    public void run();
        
}

public class Benz implements ICar {
    
    public void drive(ICar car) {
        System.out.println("Benz run ...");
    }
    
}

public class BWM implements ICar {
    
    public void drive(ICar car) {
        System.out.println("BWM run ...");
    }
    
}

public class Client {
    
    public static void mian(String[] args) {
        IDriver zhangSan = new Driver();
        ICar benz = new Benz();
        zhangSan.drive(benz);
    }
    
}