解释控制反转(IOC)概念的一个著名示例是霍利伍德(Holywood)原则,该原则规定“不要打电话给我们,我们会打电话给您”。 毫无疑问,这是一个非常准确的类比,因此有很多人将其称为类比。
通常,类创建依赖关系。 但是,IOC 为我们提供了相反的功能–只要类需要这些依赖关系,它们就可以在运行时提供给类。 您现在知道为什么霍利伍德类比如此准确吗?
课堂上没有说“不要打电话给我们,我们会打电话给您”,而是依赖项说的。
为什么这么重要? 好吧,这很重要,因为这些类可以仅专注于提供功能,而不是在正确的时间调用正确的依赖项。
IOC 到底是什么?
除了上面已经解释的内容外,还可以将控制反转(IOC)视为通常的总体工作流程的反转器,例如 高级对象处理依赖关系的方式。
反转控制(IOC)的另一个著名名称是依赖注入(DI),这意味着依赖已被正确注入,并且对象/类在对象创建中不会受到青睐,而是专注于执行正确的功能。
不使用 IOC 的顶级概述代码实现
public class WithoutIOCDemo {
static class Creature {
public void determineRaceAndSpawn(String _race) {
if (_race.equals("Human")) {
Human hum = new Human();
human.spawn();
}
else if (_race.equals("Sark")) {
Sark sark = new Sark();
sark.spawn();
}
else if (_race.equals("Mavvek")) {
Mavvek mav = new Mavvek();
mav.spawn();
}
else {
System.out.println("No such race spported. The only options are: Human, Sark and Mavvek.");
}
}
}
public static void main(String [] args) {
WithoutIOCDemo noIOC = new WithoutIOCDemo();
noIOC.determineRaceAndSpawn("Human"); // would work
}
}
从该简单示例中可以看到,defineRace
方法依赖于诸如Human
,Sark
和Mavvek
之类的较低级对象。
请注意:方法spawn()
刚刚组成,我们可以假装它存在并且按照它说的去做。
现在,让我们看一下如何通过使用 IOC 并使得defineRace
方法不依赖于较低级别的对象来获得与上述示例相同的结果。
使用 IOC 的顶层概述代码实现
public class WithIOCDemo {
Creature creature;
public WithIOCDemo(Creature creature) {
this.creature = creature;
}
public void determineRaceAndSpawn() {
this.creature.spawn();
}
public static void main(String [] args) {
Creature humanCreature = new Human();
WithIOCDemo noIOC = new WithIOCDemo(humanCreature);
noIOC.determineRaceAndSpawn(); // would work
}
}
乍一看,这种方法为我们节省了很多代码行,而且确实如此。 但是更详细一点,这也使我们的determineRaceAndSpawn()
方法不依赖于可用的Creature
种族(人类,Sark 和 Mavvek(请参考上面的示例))。 “不依赖”是指与没有 IOC 实现的示例不同,我们的方法不需要在方法中实例化相应的生物。 现在所有方法所做的就是生成生物。
简而言之,我们消除了实例化以及生成生物的负担。 现在,它只会生成它。
因此,如果将函数从determineRaceAndSpawn()
重命名为:spawnCreature()
,这将是有意义的。