依赖倒置

原则:
1、上层模块不应该依赖底层模块,它们都应该依赖于抽象
2、抽象不应该依赖于细节,细节应该依赖于抽象

  1. public class Person {
  2. // private Bike mBike;
  3. // private Car mCar;
  4. // private Train mTrain;
  5. private Driveable mDriveable;
  6. public Person() {
  7. mDriveable = new Train();
  8. }
  9. public void chumen() {
  10. System.out.println("出门了");
  11. //mBike.drive();
  12. //mCar.drive();
  13. //mTrain.drive();
  14. mDriveable.drive();
  15. }
  16. }

这里有一张人出门的照片,很形象:
1.png

依赖倒置实质上是面向接口编程的体现

控制反转(LOC)

上面的例子中需要person自己来实例化driver,而控制反转就是通过构造函数传入Driver,不管出行方式发生什么变化,person都不需要做改动。

  1. public class Person {
  2. private Driveable mDriveable;
  3. public Person(Driveable driveable) {
  4. this.mDriveable = driveable;
  5. }
  6. public void chumen() {
  7. System.out.println("出门了");
  8. mDriveable.drive();
  9. }
  10. }
  11. public class Test1 {
  12. public static void main(String[] args) {
  13. Bike bike = new Bike();
  14. Car car = new Car();
  15. Train train = new Train();
  16. // Person person = new Person(bike);
  17. // Person person = new Person(car);
  18. Person person = new Person(train);
  19. person.chumen();
  20. }
  21. }

依赖注入

为了不因为依赖实现的变动而去修改 Person, 也就是说以可能在 Driveable 实现类的改变下不改动 Person 这个类的代码,尽可能减少两者之间的耦合。我们需要采用上一节介绍的 IoC 模式来进行改写代码.
这个需要我们移交出对于依赖实例化的控制权,那么依赖怎么办?Person 无法实例化依赖了,它就需要在外部(IoC 容器)赋值给它,这个赋值的动作有个专门的术语叫做注入(injection),需要注意的是在 IoC 概念中,这个注入依赖的地方被称为 IoC 容器,但在依赖注入概念中,一般被称为注射器 (injector)。

实现依赖注入有3种方式:

  1. 构造函数中注入
  2. setter方式注入
  3. 接口注入

setter注入:

  1. public class Person {
  2. public void setDriveable(Driveable mDriveable) {
  3. this.mDriveable = mDriveable;
  4. }
  5. }

接口方式注入:

  1. public interface DepedencySetter {
  2. void set(Driveable driveable);
  3. }
  4. class Person implements DepedencySetter{
  5. private Driveable mDriveable;
  6. @Override
  7. public void set(Driveable driveable) {
  8. this.mDriveable = mDriveable;
  9. }
  10. }

在软件框架中,读取xml配置文件,或者是利用反射技术读取注解,然后根据配置信息,框架动态将一些依赖配置给特定接口的类,我们也可以说injector也依赖于接口,而不是特定的实现类,这样更进一步的提高了准确性与灵活性。

总结

  1. 控制反转是设计模式,遵从了依赖倒置的原则
  2. 依赖注入是实现控制反转的手段
  3. 本质是为了代码更加的“高内聚,低耦合”
  4. 控制反转是遵守依赖倒置这个原则而出来的一种设计模式,它引入了loc容器的概念。

在知乎上看到别人写的回答,感觉很形象
image.png

设计模式