SOLID - 依赖反转原则

  1. 1. 控制反转 IOC Inversion of Control
  2. 2. 控制反转 – 依赖注入
  3. 3. 依赖反转原则

1. 控制反转 IOC Inversion of Control

public class UserServiceTest {
  public static boolean doTest() {
    // ... 
  }

  public static void main(String[] args) {//这部分逻辑可以放到框架中
    if (doTest()) {
      System.out.println("Test succeed.");
    } else {
      System.out.println("Test failed.");
    }
  }
}

上述代码程序员在自己控制整个代码的运行顺序和执行,可以看到如果我想增加test的话,就要在main函数里面添加,同时在UserServiceTest当中添加实例。而使用框架的话,代码就可以变成如下:

public abstract class TestCase {
  public void run() {
    if (doTest()) {
      System.out.println("Test succeed.");
    } else {
      System.out.println("Test failed.");
    }
  }

  public abstract boolean doTest();
}

public class JunitApplication {
  private static final List<TestCase> testCases = new ArrayList<>();

  public static void register(TestCase testCase) {
    testCases.add(testCase);
  }

  public static final void main(String[] args) {
    for (TestCase case: testCases) {
      case.run();
    }
  }

上面的代码我们将测试的注册和运行都交给了JunitApplication了,然后我们要写新test,就让我们的concrete class extends TestCase类,来填充我们需要做的各种测试。

通过这种方式,我们实现了使用框架来控制整个代码的运转,我们使用框架来组装对象,管理整个执行流程。程序员利用框架进行开发的时候,只需要往预留的扩展点上,添加跟自己业务相关的代码,然后利用框架来驱动整个程序流程的执行。

控制反转是一种思想,有很多的具体的实现方式

2. 控制反转 – 依赖注入

是控制反转的一种具体实现的方式,他的实际操作的指南是 – 不通过new()的方式在类内部创建依赖类的对象,而是将依赖的类对象在外部创建好以后,通过构造函数,函数参数的方式传递进来给类使用。

// 非依赖注入实现方式
public class Notification {
  private MessageSender messageSender;

  public Notification() {
    this.messageSender = new MessageSender(); //此处有点像hardcode
  }

  public void sendMessage(String cellphone, String message) {
    //...省略校验逻辑等...
    this.messageSender.send(cellphone, message);
  }
}

public class MessageSender {
  public void send(String cellphone, String message) {
    //....
  }
}
// 使用Notification
Notification notification = new Notification();

// 依赖注入的实现方式
public class Notification {
  private MessageSender messageSender;

  // 通过构造函数将messageSender传递进来
  public Notification(MessageSender messageSender) {
    this.messageSender = messageSender;
  }

  public void sendMessage(String cellphone, String message) {
    //...省略校验逻辑等...
    this.messageSender.send(cellphone, message);
  }
}
//使用Notification
MessageSender messageSender = new MessageSender();
Notification notification = new Notification(messageSender);

使用依赖注入的最大好处就是,我们不需要在具体的类当中实例化其他的类,这样就实现了解耦,即他的具体实现我们可以在外部做其他方式的实例,这个时候多态也可以派上用场。可以想成我在类的内部占了个座,至于这个座具体要给谁坐,怎么坐,得等到节目要开始之前再来安排,这样我就可以举办不同的活动了。

public class Notification {
  private MessageSender messageSender;

  public Notification(MessageSender messageSender) {
    this.messageSender = messageSender;
  }

  public void sendMessage(String cellphone, String message) {
    this.messageSender.send(cellphone, message);
  }
}

public interface MessageSender {
  void send(String cellphone, String message);
}

// 短信发送类
public class SmsSender implements MessageSender {
  @Override
  public void send(String cellphone, String message) {
    //....
  }
}

// 站内信发送类
public class InboxSender implements MessageSender {
  @Override
  public void send(String cellphone, String message) {
    //....
  }
}

//使用Notification
MessageSender messageSender = new SmsSender();
Notification notification = new Notification(messageSender);

3. 依赖反转原则

依赖反转 – Dependency Inversion Principle

High-level modules shouldn’t depend on low-level modules. Both modules should depend on abstractions. In addition, abstractions shouldn’t depend on details. Details depend on abstractions.

高层模块(high-level modules)不要依赖低层模块(low-level)。高层模块和低层模块应该通过抽象(abstractions)来互相依赖。除此之外,抽象(abstractions)不要依赖具体实现细节(details),具体实现细节(details)依赖抽象(abstractions)。


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 stone2paul@gmail.com

文章标题:SOLID - 依赖反转原则

文章字数:903

本文作者:Leilei Chen

发布时间:2020-03-19, 11:53:05

最后更新:2020-03-19, 11:53:34

原始链接:https://www.llchen60.com/SOLID-%E4%BE%9D%E8%B5%96%E5%8F%8D%E8%BD%AC%E5%8E%9F%E5%88%99/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录
×

喜欢就点赞,疼爱就打赏