Inversion of Control Principle
Ioc is all about inverting the control in object-oriented design to achieve loose coupling.
Loose coupling is an approach of interconnecting different parts of a system in a way, one part is least depended on the other. It’s main purpose is to limit any additional changes to other parts of the system when a component is changed.
Control refers to any responsibilities a class can have. This includes, control over the flow of an application, control over the lifecycle of objects and object dependency creation and binding.
Code sample without Ioc
Problems with this implementation
- Tightly coupled classes. Any changes to the ContractDAO will affect ContractBusinessLogic, as ContractBusinessLogic depends on the concrete class ContractDAO. Adding, removing or altering methods in ContractDAO will affect ContractBusinessLogic as well.
- Using ‘new ContractDAO’ in ContractBusinessLogic, will affect all classes in the system using this class, in case it changes name.
- ContractBusinessLogic creates a concrete class of ContractDAO. It cannot be replaced with a mock class in a Test Driven Design and tested without the concrete implementation.
Solution using Factory pattern
Inverting the control to DAOFactory
Problem
DAOFactory class is used inside the ContractBusinessLogic class. If there is another implementation of IContractDAO, we need to change DAOFactory and ContractBusinessLogic as well.
The above solution does not entirely support loose coupling. Dependency Inverstion Principle, Dependency Injection and Strategy pattern is also needed.
Dependency Inversion Principle definition
High-level modules should not depend on low-level modules. Both should depend on the abstraction.
Abstractions should not depend on details. Details should depend on abstractions.
We need to create an injector class DependencyInjection class which injects the IContractDAO implementation to ContractBusinessLogic class.
Some of the advantages with this approach
- Code becomes more modular
- Loose coupling
- More flexibility by injecting dependencies at runtime
Dependency Injection and Strategy pattern can be used to create loose coupled classes.
For more advanced applications, implementing these patterns is time consuming and requires a lot of effort. Here is where the IoC Container comes to the rescue.
Well known IoC Containers
- Spring IoC Container (java)
- Unity (.Net)