原文: https://javatutorial.net/ioc-in-spring

解释控制反转(IOC)概念的一个著名示例是霍利伍德(Holywood)原则,该原则规定“不要打电话给我们,我们会打电话给您”。 毫无疑问,这是一个非常准确的类比,因此有很多人将其称为类比。

Spring IOC - 图1

通常,类创建依赖关系。 但是,IOC 为我们提供了相反的功能–只要类需要这些依赖关系,它们就可以在运行时提供给类。 您现在知道为什么霍利伍德类比如此准确吗?

课堂上没有说“不要打电话给我们,我们会打电话给您”,而是依赖项说的。

为什么这么重要? 好吧,这很重要,因为这些类可以仅专注于提供功能,而不是在正确的时间调用正确的依赖项。

IOC 到底是什么?

除了上面已经解释的内容外,还可以将控制反转(IOC)视为通常的总体工作流程的反转器,例如 高级对象处理依赖关系的方式。

反转控制(IOC)的另一个著名名称是依赖注入(DI),这意味着依赖已被正确注入,并且对象/类在对象创建中不会受到青睐,而是专注于执行正确的功能。

不使用 IOC 的顶级概述代码实现

  1. public class WithoutIOCDemo {
  2. static class Creature {
  3. public void determineRaceAndSpawn(String _race) {
  4. if (_race.equals("Human")) {
  5. Human hum = new Human();
  6. human.spawn();
  7. }
  8. else if (_race.equals("Sark")) {
  9. Sark sark = new Sark();
  10. sark.spawn();
  11. }
  12. else if (_race.equals("Mavvek")) {
  13. Mavvek mav = new Mavvek();
  14. mav.spawn();
  15. }
  16. else {
  17. System.out.println("No such race spported. The only options are: Human, Sark and Mavvek.");
  18. }
  19. }
  20. }
  21. public static void main(String [] args) {
  22. WithoutIOCDemo noIOC = new WithoutIOCDemo();
  23. noIOC.determineRaceAndSpawn("Human"); // would work
  24. }
  25. }

从该简单示例中可以看到,defineRace方法依赖于诸如HumanSarkMavvek之类的较低级对象。

请注意:方法spawn()刚刚组成,我们可以假装它存在并且按照它说的去做。

现在,让我们看一下如何通过使用 IOC 并使得defineRace方法不依赖于较低级别的对象来获得与上述示例相同的结果。

使用 IOC 的顶层概述代码实现

  1. public class WithIOCDemo {
  2. Creature creature;
  3. public WithIOCDemo(Creature creature) {
  4. this.creature = creature;
  5. }
  6. public void determineRaceAndSpawn() {
  7. this.creature.spawn();
  8. }
  9. public static void main(String [] args) {
  10. Creature humanCreature = new Human();
  11. WithIOCDemo noIOC = new WithIOCDemo(humanCreature);
  12. noIOC.determineRaceAndSpawn(); // would work
  13. }
  14. }

乍一看,这种方法为我们节省了很多代码行,而且确实如此。 但是更详细一点,这也使我们的determineRaceAndSpawn()方法不依赖于可用的Creature种族(人类,Sark 和 Mavvek(请参考上面的示例))。 “不依赖”是指与没有 IOC 实现的示例不同,我们的方法不需要在方法中实例化相应的生物。 现在所有方法所做的就是生成生物。

简而言之,我们消除了实例化以及生成生物的负担。 现在,它只会生成它。

因此,如果将函数从determineRaceAndSpawn()重命名为:spawnCreature(),这将是有意义的。