设计模式之美学习-控制反转、依赖反转、依赖注入(八)

什么是控制反转(IOC)

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.");
    }
  }
}

上面代码所有代码都由开发人员控制

控制反转例子

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();
        }
    }
}

以上代码是一个简单的测试框架例子代码

使用

public class UserServiceTest extends TestCase {
  @Override
  public boolean doTest() {
    // ... 
  }
}

// 注册操作还可以通过配置的方式来实现,不需要程序员显示调用register()
JunitApplication.register(new UserServiceTest();

新增一个用户的实现

控制反转  控制代表框架  将由开发人员控制执行流程 反转给框架

依赖注入(DI)

不要将类依赖的对象 使用直接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);

依赖注入框架(DI Framework)

在现实开发中  一个类可能依赖几十个上百个类,如果都采用手动new的方式 代码会非常臃肿和复杂

现成的依赖注入框架有很多,比如 Google Guice、Java Spring、Pico Container、Butterfly Container 等。不过,如果你熟悉 Java Spring 框架,你可能会说,Spring 框架自己声称是控制反转容器(Inversion Of Control Container)

将创建对象的和管理对象声明周期的控制权交给反转给框架 通过DI解决类与类之间依赖关系

 

依赖反转原则(DIP)

同时也叫依赖倒置原则

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

posted @ 2020-01-02 16:34  意犹未尽  阅读(171)  评论(0编辑  收藏  举报