IOC in Spring

A famous example of explaining the Inversion of Control (IOC) concept is the Holywood principle which states “Dont’ call us, we will call you”. Without a doubt, it is a very accurate analogy, hence the amount of people referencing it as an analogy.

spring-featured-image

Usually, classes create dependencies. However, IOC gives us the opposite functionality – the dependencies are made available to the classes at runtime whenever the classes need these dependencies. Can you see now why the Holywood analogy is so accurate?

Instead of the classes saying “Don’t call us, we will call you”, it is the dependencies saying that.

Why is that important? Well, it is important because the classes can simply focus on delivering the functionality instead of calling the right dependencies at the right time.




What exactly is IOC?

In addition to what I have explained above, think of Inversion of Control (IOC) as an invertor of the usual overall workflow, e.g. the way high-level objects handle dependencies.

Another famous name that is given to Inversion of Control (IOC) is Dependency Injection (DI) which means that the dependencies have been injected properly and that the objects/classes do not get invloved in object creation but concentrate on executing the correct functionality.

Top-level overview code implementation without the use of 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
	}
	
}

As you can see from that simple example, the determineRace method is dependent on the lower-level objects, like Human, Sark and Mavvek.

Please note: the method spawn() is just made up, we can just pretend that it exists and does what it says.

Now, let’s see how we could achieve the same result as the example above by using IOC and making the determineRace method not dependent on the lower level objects.

Top-level overview code implementation WITH the use of 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
	}
	
}

At first glance, this method saves us a lot of lines of code, and it does. But in a little more detail, it also makes our determineRaceAndSpawn() method not dependent on the available Creature races (Human, Sark and Mavvek (Reference the Example above this one)). By “not dependent” I mean unlike the example without the IOC implementation, our method does not need to instatiate the corresponding Creature within the method. All the method does now is spawn the creature.

In short, we eliminated the burden of both instantiating a creature and spawning it. Now, it only spawns it.

Therefore, it would make sense if we renamed the function from determineRaceAndSpawn() to: spawnCreature().

Leave a Reply

avatar