Inversion of Control (IOC)

G. Abhisek
Swift India
Published in
5 min readApr 26, 2020

Have you encountered the following in your code:

  • Your components are not that small and cute as they used to be while starting your development.
  • Components in your code produce undesired side effects that are hard to debug.
  • The components you write keep on becoming bulkier if multiple use cases and logic are encountered.
  • Classes are becoming difficult to test might be due to their size or lack of separation of concerns.

If you have reeled with these then following principles of IOC will definitely be a lifesaver.

Concepts of IOC date back to 1985 when Ralph E. Johnson & Brian Foote shared their research paper on Designing Reusable Classes.

Inversion of Control as the name suggests is to invert control for loose coupling between components making them smaller, testable, and reusable.

What do you mean by inverting the control?

Let us take an example where you are Batman who gets his morning newspaper from Mr. Alfred, the news agent. Even though you are Batman, you don’t get your morning news whenever Mr. Alfred goes on vacation. You are very dependent on Mr. Alfred for getting your newspaper. For a solution, you directly now reach out to the agency of Mr. Alfred, i.e Gotham Publications to supply your newspapers. In this case, you will either get your newspaper by Mr. Alfred or by any other agents as the agency deems to make sure you have an uninterrupted supply.

You gave the control of delivering your newspaper to the agency which has a number of agents to get the job done. You inverted the control or inverted the control of newspaper delivery from Mr. Alfred to the news agency

You are Batman … !!

If you simulate this situation of yours via code, that would look something like below. We will use Swift as a programming language for the examples.

Before you appointed news agency

Alfred delivers your newspaper

You hired Alfred to deliver newspaper agent Alfred for delivering newspaper creating a dependency on Alfred.

After you appointed a news agency

Get your newspaper from the news agency

Now you have modified the structure of your house accepting a newspaper agency, here Gotham Publications. The newspaper agency has many agents, Alfred can be one of them. So you now ask the agency to get a newspaper agent who in turn delivers the newspaper when you start your morning activities. Thus you removed the tight coupling or dependency that you had with your agent directly.

Inversion of Control and Dependency Injection

Speaking about dependency did you notice the Dependency Injection that we had introduced in the above code snippet when you appointed an agency to deliver your newspaper.

Dependency Injection is a technique to achieve IOC. You did not actually depend on NewsAgency rather you depended on an abstracted version of the same. You depended on a protocol NewsAgentProvidable that could provide you with a newspaper agent who in turn provides you with a newspaper.

If you don’t have an idea of Dependency Injection. Do yourself a favor and read about the same.

Inversion of Control while designing Frameworks

Inversion of control could come quite handy while you are designing frameworks. Let us say you are building a mobile app. You are designing a framework that makes certain web service calls and on success provides you back with the Data Model or if encountered with any error handles that by notifying the user.

There are two ways in which you can design the flow of the above functionality:

Approach 1: Framework consumer takes control of the program flow

The consumer of the WebserviceFramework now controls the flow of events when it says:

  • performRequest to perform web service calls.
  • URLSession is an iOS framework to perform network requests to a server.
  • Upon receiving the completion from the framework, the program now analyses the result and again calls the framework to handle the errors.
  • The framework displays an alert to the user regarding the error and upon acknowledgment, your code calls the framework again to dismiss the error alert.

This approach has the following caveats:

  • You can not easily replace the framework with any other framework which does not have a similar API to avoid minimal changes.
  • Learning the framework for any new user would be difficult because the methods needed to perform the functionalities of this framework will be huge.
  • Debugging the program flow will be difficult based on how the user program calls the framework APIs.

These types of frameworks are known as white-box frameworks.

Approach 2: Framework controls the program flow

With this approach, your framework performs the same network request but controls the error handling mechanism internally. Your code still passes all the required configurations such as a view to present the alert on and a completion callback to the framework via the setUpBinding() to the framework. These are known as black-box frameworks.

How to achieve IOC?

IOC can be achieved in many ways. We have already seen Dependency Injection in our newspaper example. I would say if by any means you can segregate your code avoiding tight coupling and with a defined set of functionality just as in the case of a black-box framework, you have achieved IOC. A few of the approaches that we can follow to achieve IOC:

The overall takeaway of the blog would be to keep your code segregated and maintain a clear separation of concerns. A segregated code should be reusable and behave as a plugin and plug out component inside your code providing it with input and configurations and letting it perform its actions and give back you the output.

I would love to hear from you

You can reach me for any query, feedback, or just want to have a discussion by the following channels:

Twitter — @gabhisek_dev

LinkedIn

Please feel free to share with your fellow developers.

--

--